Vignette - Computational proteomics of a THP-1 human leukaemia cell line
1 Abstract
This vignette contains the R1 pipeline used for the computational analysis reported in the paper “Spatiotemporal proteomic profiling of the pro-inflammatory response to lipopolysaccharide in the THP-1 human leukemia cell line” by Mulvey, Breckels et al.2
2 Introduction
In this vignette we work with the data at the PSM and protein level which which are freely and openly available as part of the Bioconductor pRolocdata package (≥v1.27.3)3 and in the supplementary information as disseminated with the accompanying manuscript.2
All analysis in the manuscript is done in the R programming language, unless otherwise stated, using the suite of mass spectrometry spatial proteomics packages MSnbase4, pRoloc3, pRolocGUI and pRolocdata.
All raw mass spectrometry proteomics data from this study have been deposited to the ProteomeXchange Consortium via the PRIDE partner repository,5 with the dataset identifier PXD023509.
2.1 Before you start
To run through the code in this vignette please download the THP LOPIT Github repository, the R programming language and we also recommend you download RStudio IDE which is a great interface to R.
Please open RStudio and navigate to the thp-lopit-2021 directory you have just saved and downloaded. To do this go to menu
Session -> Set Working Directory -> Choose Directory …
If you type getwd into the R console. You should see the directory name in your path. For more information on how to use RStudio please see RStudio education website for some nice introductory tutorials.
2.2 Accessing the data in R
The pRolocdata package is a R Bioconductor experiment package that collects mass spectrometry-based spatial/organelle and protein-complex datasets from published experiments. Each data is stored in a container called a MSnSet instance (see the MSnbase for details) which allows users to work seamlessly with the R pRoloc and pRolocGUI software for spatial proteomics data analysis and visualisation.
The first step is to install the pRoloc and pRolocdata packages from Bioconductor
if (!requireNamespace("BiocManager", quietly = TRUE))
install.packages("BiocManager")
BiocManager::install("pRoloc", "pRolocdata")
## we also use the knitr and VennDiagram, ggplot2 packages in this
## vignette so please install if you do not have them
BiocManager::install(c("knitr", "VennDiagram", "ggplot2", "dplyr", "kableExtra",
"coda", "reshape2", "circlize", "ggalluvial", "tidyr",
"Rmisc", "gridExtra", "gplots", "scico", "plotrix",
"RColorBrewer"))Note: To access the widest selection on proteomics datasets we advise users to install the latest version pRolocdata package from Bioconductor. The THP data is in version >=1.29.1
Now we can load the packages by calling library function in R
and subsequently we can now access all the datasets in pRolocdata. To list all available datasets we use the data function.
We see there are 27 datasets (including the PSM and protein level data) associated with the manuscript [1], 20 from the hyperLOPIT data anlysis and 7 from the LPS timecourse.2 For more information on these datasets, we can type
Figure 2.1: Screenshot of the documentation files in R for the THP LOPIT and LPS timecourse datasets
Each dataset can be loaded using the data function. For example, to load the final protein level LOPIT datasets for the unstimulated and 12 hour LPS stimulated datasets,
data("thpLOPIT_unstimulated_mulvey2021")
thpLOPIT_unstimulated_mulvey2021
data("thpLOPIT_lps_mulvey2021")
thpLOPIT_lps_mulvey2021In the next sections we introduce the data, experimental design and brief overview of the experimental protocol before walking users through the downstream analysis which was used to generate the datasets available in pRolocdata and the manuscript Mulvey et al 2021.2
2.3 Source code
All the core packages that we use for data analysis, namely MSnbase, pRolocdata, pRolocdata and pRolocGUI are all freely and openly available on R/Bioconductor and Github. Specific code and functions used that have been used throughout this workflow for analysis and generating figures can be found in the r directory of this repo.
3 Temporal proteomics data analysis
3.1 Summary
We assessed the global proteomic landscape of the THP-1 monocytic leukaemic cell line using a shotgun proteomics time course. Total (unfractionated) cell lysates were collected at 0, 2, 4, 6, 12, and 24 hour time-points following LPS stimulation and processed for quantitative, MS-based proteomics analysis. We reproducibly quantified 4,292 proteins across 3 biological replicate experiments, at all time-points. In total 311 proteins were found to be altered in abundance during the time course of LPS stimulation, with statistical significance (adjusted p-value < 0.01, log_2 fold-change > 0.6). The results are reported in full in Mulvey et al. 2021.2
3.2 PSM level data processing
The 3 PSM level datasets were imported into R and missing values were carefully assessed.
We can load the PSM and protein level data from the pRolocdata package by using the data function.
## Unstimulated data
data("psms_lpsTimecourse_rep1_mulvey2021")
data("psms_lpsTimecourse_rep2_mulvey2021")
data("psms_lpsTimecourse_rep3_mulvey2021")
psms_lpsTimecourse_rep1_mulvey2021## MSnSet (storageMode: lockedEnvironment)
## assayData: 34640 features, 6 samples
## element names: exprs
## protocolData: none
## phenoData
## sampleNames: 0 hr rep 1 2 hr rep 1 ... 24 hr rep 1 (6 total)
## varLabels: Tag Time Replicate
## varMetadata: labelDescription
## featureData
## featureNames: 1 2 ... 34640 (34640 total)
## fvarLabels: Checked Confidence ... PSM.count (42 total)
## fvarMetadata: labelDescription
## experimentData: use 'experimentData(object)'
## Annotation:
## - - - Processing information - - -
## Subset [218958,6][34640,6] Tue Jan 12 14:42:27 2021
## MSnbase version: 2.14.2
## [1] 34640 6
## MSnSet (storageMode: lockedEnvironment)
## assayData: 49806 features, 6 samples
## element names: exprs
## protocolData: none
## phenoData
## sampleNames: 0 hr rep 2 2 hr rep 2 ... 24 hr rep 2 (6 total)
## varLabels: Tag Time Replicate
## varMetadata: labelDescription
## featureData
## featureNames: 34641 34642 ... 84446 (49806 total)
## fvarLabels: Checked Confidence ... PSM.count (42 total)
## fvarMetadata: labelDescription
## experimentData: use 'experimentData(object)'
## Annotation:
## - - - Processing information - - -
## Subset [218958,6][49806,6] Tue Jan 12 14:42:27 2021
## MSnbase version: 2.14.2
## [1] 49806 6
## MSnSet (storageMode: lockedEnvironment)
## assayData: 41853 features, 6 samples
## element names: exprs
## protocolData: none
## phenoData
## sampleNames: 0 hr rep 3 2 hr rep 3 ... 24 hr rep 3 (6 total)
## varLabels: Tag Time Replicate
## varMetadata: labelDescription
## featureData
## featureNames: 84447 84448 ... 126299 (41853 total)
## fvarLabels: Checked Confidence ... PSM.count (42 total)
## fvarMetadata: labelDescription
## experimentData: use 'experimentData(object)'
## Annotation:
## - - - Processing information - - -
## Subset [218958,6][41853,6] Tue Jan 12 14:42:27 2021
## MSnbase version: 2.14.2
## [1] 41853 6
The summary above tells us that 34640, 49806 and 41853 PSMs were detected in replicates 1, 2 and 3, respectively.
In the below code chunk we put the replicates into a MSnSetList for ease of data processing.
psms <- MSnSetList(list(psms_lpsTimecourse_rep1_mulvey2021,
psms_lpsTimecourse_rep2_mulvey2021,
psms_lpsTimecourse_rep3_mulvey2021))3.2.1 Missing values assessent
It is important to examine any missing values, whether they are biological or technical. In MS proteomics experiments that use isobaric labelling, such as we have here, we find very few missing values and it is easy to examine them on case-by-case basis. In the below code chunks we indeed see that there are very few PSMs with missing values after filtering. There are 19 missing values in rep 1, 7 in rep2, and 16 in rep3.
As we have such few missing values we begin by assessing if we have any other PSMs corresponding to the same protein group available for quantitation. The below code chunk counts the number of PSMs available for a protein group, for those protein groups which have missing values.
## Display number of PSMs for each protein with a MV
xx <- lapply(psms, function(z) which(apply(exprs(z), 1, anyNA)))
(numpsms <- sapply(seq(psms), function(y)
{sapply(fData(psms[[y]])$Master.Protein.Accessions[xx[[y]]],
function(z) length(which(fData(psms[[y]])$Master.Protein.Accessions
== z)))}))## [[1]]
## P04179 P04179 P09914 O14879 P06307 Q8TCB0 P09601 P09601
## 6 6 15 25 1 2 15 15
## O14879 P09913 P00973 P01584 P04075 Q9BYX4 O14879 P20591
## 25 16 7 7 84 12 25 41
## P29728-2 Q9BYX4 Q13501
## 15 12 12
##
## [[2]]
## O14879 P04179 P12956 P09913 O14879 P09601 P11388-4
## 33 11 55 19 33 24 43
##
## [[3]]
## P20591 P09914 Q13501 P20591 P20591 Q9BYX4 P20591 O14879
## 68 21 14 68 68 9 68 30
## Q15833 Q96J88-2 P05362 P09913 Q9BYK8 Q96J88-2 O14879 P20592
## 16 8 19 13 17 8 30 38
## 1 2 3
## 19 7 16
We find that there is only one singleton PSM (one protein group with one only PSM for quantitation) in rep 1 (P06307). The below code chunk plots the PSM quantitation profiles of every protein group that has a missing PSM. Red triangles highlight the missing value.
## plot reps
plotMV <- function(r) {
tochk <- unique(names(numpsms[[r]]))
for (i in 1:length(tochk)) {
mm <- exprs(psms[[r]])[which(fData(psms[[r]])$Master.Protein.Accessions == tochk[i]), , drop = FALSE]
matplot(t(mm), type = "l", xlab = "", ylab = "m/z", lwd = 2,
main = tochk[i], col = "grey", axes = FALSE)
axis(2)
axis(1, at = 1:ncol(mm), labels = colnames(mm), las = 2)
if (any(is.na(mm))) {
ycoord <- sapply(1:ncol(mm), function(z) which(is.na(mm[, z])))
.l <- sapply(ycoord, length)
.xi <- which(.l > 0)
xcoord <- unlist(lapply(1:length(.xi), function(z) rep(.xi[z], .l[.xi[z]])))
ycoord <- unlist(ycoord)
points(x = xcoord, y = ycoord, bg = "red", col = "black", pch = 24, cex = 1.5)}
}
}
par(mfrow = c(4, 4))
plotMV(r = 1)
par(mfrow = c(2, 4))
plotMV(r = 2)
par(mfrow = c(3, 4))
plotMV(r = 3)Figure 3.1: PSM quantitation profile plots are shown for protein groups which contained a PSM with a missing value. The red triangles show the location of the missing values in the timecourse
Looking at the above plots we see for the PSMs that are missing there are two general trends (1) they occur at the lower end/start of the time course, (2) missing PSMs tend to appear at the beginning of the time-course and show the same trend over time (a few exceptions listed below)
Given these two observations we decide for the majority of PSMs to use a left-censored imputation approach. It wouldn’t be appropriate for a few cases and these are P06307, P04075 in rep 1, P113388-4, P12956 in rep 2 and so for these PSMs we will use k-nearest neighbour (k-NN), and thus we use a mixed imputation strategy. We remove the PSM at row 31435 for the protein group P12956 as it has 5 missing values out of 6, and there are many other PSMs available for protein quantitation.
Type ?impute in your R console for more information on missing values imputation methods available in the MSnbase and pRoloc pipeline.
Imputation is done using the impute function in MSnbase
## Split the data by replicate
psms_rep1 <- psms[[1]]
psms_rep2 <- psms[[2]]
psms_rep3 <- psms[[3]]
## define psms which are missing at random - see ?impute
fData(psms_rep1)$randna <- FALSE
fData(psms_rep1)$randna[11237] <- TRUE # P06307
fData(psms_rep1)$randna[26194] <- TRUE # P04075
# remove missing this PSM for protein P12956 as it has 5 missing values out of the 6 timepoints
# remove PSM 48162 for protein P113388-4 as 42 other PSMs available and it has no clear trend
psms_rep2 <- psms_rep2[-c(31435, 48162), ]
## replicate 1 imputation
psms_rep1 <- impute(psms_rep1, "mixed",
randna = fData(psms_rep1)$randna,
mar = "knn",
mnar = "MinDet")
## replicate 2 imputation
psms_rep2 <- impute(psms_rep2, "MinDet")
## replicate 3 imputation
psms_rep3 <- impute(psms_rep3, "MinDet")
## Re-create MSnSetList of the data
psms <- MSnSetList(list(rep1 = psms_rep1, rep2 = psms_rep2, rep3 = psms_rep3))We can check these look sensible by re-plotting them again.
## Display number of PSMs for each protein with a MV
numpsms <- sapply(seq(psms), function(y)
{sapply(fData(psms[[y]])$Master.Protein.Accessions[xx[[y]]],
function(z) length(which(fData(psms[[y]])$Master.Protein.Accessions
== z)))})
par(mfrow = c(4, 4))
plotMV(r = 1)
par(mfrow = c(2, 4))
plotMV(r = 2)
par(mfrow = c(3, 4))
plotMV(r = 3)3.2.2 Data normalisation
The data was visually assessed by examining pairwise scatter plots and MAplots of the data and then normalised using vsn followed by diff.median.
## make all PSMs uppercase so that PSMs with different PTMs are not
## considered as different sequences
for (i in seq(psms))
fData(psms@x[[i]])$Annotated.Sequence <- toupper(fData(psms@x[[i]])$Annotated.Sequence)
## combine the data and normalise
cmb <- MSnbase::combine(psms[[1]], psms[[2]])
cmb <- MSnbase::combine(cmb, psms[[3]])
dim(cmb)
## Let's have a look at the intensities
boxplot(log(exprs(cmb)))## Try a few different normalisation approaches
cmb.vsn <- normalise(cmb, "vsn")
cmb.median <- normalise(cmb, "diff.median")
cmb.vsn.median <- normalise(cmb.vsn, "diff.median")
cmb.quantiles <- normalise(cmb, "quantiles")
## Plot the data
par(mfrow = c(2, 3), las = 2, oma = c(6, 1, 1, 1))
boxplot(log(exprs(cmb)), main = "method = untransformed", ylab = "log intensity")
boxplot(log(exprs(cmb.median)), main = "method = diff.median", ylab = "log intensity")
boxplot(exprs(cmb.vsn), main = "method = vsn", ylab = "log intensity") # NOTE: VSN internally logs the data
boxplot(log(exprs(cmb.vsn.median)), main = "method = vsn + diff.median", ylab = "log intensity")
boxplot(log(exprs(cmb.quantiles)), main = "method = quantiles", ylab = "log intensity")
## We decide to go with 'vsn' followed by 'diff.median'
cmb <- cmb.vsn.median3.2.3 Aggregation to protein
We use the combineFeatures function from MSnbase to aggregate to protein level.
psms1 <- filterNA(cmb[, 1:6])
psms2 <- filterNA(cmb[, 7:12])
psms3 <- filterNA(cmb[, 13:18])
psms <- MSnSetList(list(psms1, psms2, psms3))
## Aggregate to protein using median PSM per protein group
prots <- lapply(seq(psms), function(z)
combineFeatures(psms[[z]],
groupBy = fData(psms[[z]])$Master.Protein.Accession,
method = "median", verbose = FALSE))
## Do data fusion - create concatenated complete dataset
prots[[1]] <- updateFvarLabels(prots[[1]])
prots[[2]] <- updateFvarLabels(prots[[2]])
prots[[3]] <- updateFvarLabels(prots[[3]])
cmbprots <- MSnbase::combine(prots[[1]], prots[[2]])
cmbprots <- MSnbase::combine(cmbprots, prots[[3]])
cmbprots <- MSnbase::filterNA(cmbprots)
dim(cmbprots)## [1] 4292 18
We identify 5221, 5812 and 5210 proteins in replicates 1, 2 and 3, respectively, and a total of 4292 common across all channels and timepoints in all samples.
3.3 Protein level data processing
We load the individual protein level datasets from pRolocdata using the data function.
data("lpsTimecourse_rep1_mulvey2021")
data("lpsTimecourse_rep2_mulvey2021")
data("lpsTimecourse_rep3_mulvey2021")
lpsTimecourse_rep1_mulvey2021## MSnSet (storageMode: lockedEnvironment)
## assayData: 5221 features, 6 samples
## element names: exprs
## protocolData: none
## phenoData
## sampleNames: X0.hr.rep.1 X2.hr.rep.1 ... X24.hr.rep.1 (6 total)
## varLabels: Tag Time Replicate
## varMetadata: labelDescription
## featureData
## featureNames: A0AVT1 A0FGR8-2 ... Q9Y6Y8 (5221 total)
## fvarLabels: Checked.rep1 Confidence.rep1 ... Peptides.count.rep1 (44
## total)
## fvarMetadata: labelDescription
## experimentData: use 'experimentData(object)'
## Annotation:
## - - - Processing information - - -
## MSnbase version: 2.14.2
## [1] 5221 6
## MSnSet (storageMode: lockedEnvironment)
## assayData: 5812 features, 6 samples
## element names: exprs
## protocolData: none
## phenoData
## sampleNames: X0.hr.rep.2 X2.hr.rep.2 ... X24.hr.rep.2 (6 total)
## varLabels: Tag Time Replicate
## varMetadata: labelDescription
## featureData
## featureNames: A0A0B4J2F0 A0AV96 ... Q9Y6Y8 (5812 total)
## fvarLabels: Checked.rep2 Confidence.rep2 ... Peptides.count.rep2 (43
## total)
## fvarMetadata: labelDescription
## experimentData: use 'experimentData(object)'
## Annotation:
## - - - Processing information - - -
## MSnbase version: 2.14.2
## [1] 5812 6
## MSnSet (storageMode: lockedEnvironment)
## assayData: 5210 features, 6 samples
## element names: exprs
## protocolData: none
## phenoData
## sampleNames: X0.hr.rep.3 X2.hr.rep.3 ... X24.hr.rep.3 (6 total)
## varLabels: Tag Time Replicate
## varMetadata: labelDescription
## featureData
## featureNames: A0AV96 A0AVT1 ... Q9Y6Y8 (5210 total)
## fvarLabels: Checked.rep3 Confidence.rep3 ... Peptides.count.rep3 (43
## total)
## fvarMetadata: labelDescription
## experimentData: use 'experimentData(object)'
## Annotation:
## - - - Processing information - - -
## MSnbase version: 2.14.2
## [1] 5210 6
We see we have 5221, 5812 and 5210 proteins for replicates 1, 2 and 3, respectively.
3.3.1 Data fusion
Data is concatenated into one matrix using the combine function in MSnbase and then proteins not common across all replicates are removed by using the filterNA function.
cmb <- MSnbase::combine(lpsTimecourse_rep1_mulvey2021,
lpsTimecourse_rep2_mulvey2021)
cmb <- MSnbase::combine(cmb, lpsTimecourse_rep3_mulvey2021)
cmb <- filterNA(cmb)
dim(cmb)## [1] 4292 18
We find 4292 proteins common across all timepoints in all replicates.
## Function to add Gene Names to the data for adding Gene Name labels when we plot the results
source("r/getGN.R")
cmb <- addGeneName(cmb, fcol = "Protein.Descriptions.rep1", col.name = "GN")Note: the combined dataset is also available directly from pRolocdata type data("lpsTimecourse_mulvey2021")
We use the venn.diagram function from the VennDiagram package to draw venns of the data.
library("VennDiagram")
## lps timecourse
venn.diagram(
x = list(featureNames(lpsTimecourse_rep1_mulvey2021),
featureNames(lpsTimecourse_rep2_mulvey2021),
featureNames(lpsTimecourse_rep3_mulvey2021)),
category.names = c("Replicate 1" , "Replicate 2 " , "Replicate 3"),
filename = "figures/venn_TC_replicates.png",
main = "LPS timecourse: 0-24h",
col=c("#440154ff", '#21908dff', '#D6BA0D'),
fill = c(alpha("#440154ff",0.3), alpha('#21908dff',0.3), alpha('#D6BA0D',0.3)),
fontfamily = "sans",
cat.fontfamily = "sans",
main.fontfamily = "sans",
cat.col = c("#440154ff", '#21908dff', '#D6BA0D'),
cat.cex = 1.2,
main.cex = 1.6,
cex = 1.7,
cat.fontface = 2,
cat.dist = c(0.07, 0.07, 0.03),
sub = "",
output = FALSE
)Figure 3.2: Proteins common across LPS timecourse replicates
3.4 Protein expression analysis
3.4.1 Batch effects
Before we can have a look at changes in protein expression we first need to check if we see any batch effects. We plot the data by ‘Tag’ and ‘Replicate’ to see if this may be the case.
par(mfrow = c(1, 2))
plot2D(t(cmb), fcol = "Tag", main = "PCA: TMT tag")
plot2D(t(cmb), fcol = "Replicate", main = "PCA: Replicates")Figure 3.3: PCA plots showing of the effect of TMT tag and replicate on the intensities
We see clearly from the PCA that the samples are confounded by replicate. We can correct for this by using limma. The limma package in Bioconductor provides a number of linear models that can accommodate complex experimental designs and account for experimental technicalities such as batch effects and confounding factors. To statistically analyse relative abundance we use limma’s empirical Bayes moderated t-test, a shrinkage method appropriate for small sample sizes (see Smyth’s paper: http://www.ncbi.nlm.nih.gov/pubmed/16646809). A paired t-test is valid as experiments within each replicate use the same lysate.
3.4.2 Differential protein expression analysis
We use the classic eBayes method in the limma package using lmFit and add Replicate to the model matrix so we can account for this confounding factor
i.e. design <- model.matrix(~Replicate+Time).
limma takes care of these potential batch effects.
In the next sections we perform differential expression analysis using the limma package.6 We first load some code for generating volcano plots.
3.4.2.1 24 hour timepoint
The below results of the differential analysis at each time point are written to the csv directory of this repo, Supplementary Table 1 of Mulvey et al 2021 and are also stored in the fData of the lpsTimecourse_mulvey2021 dataset found in pRolocdata for easy access.
library("limma")
## 0hr and 24hr
i <- grep("X0.hr", sampleNames(cmb))
j <- grep("X24.hr", sampleNames(cmb))
eset <- cmb[, c(i, j)]
data <- exprs(eset)
rownames(data) <- fData(cmb)[["GN"]]
head(data)## X0.hr.rep.1 X0.hr.rep.2 X0.hr.rep.3 X24.hr.rep.1 X24.hr.rep.2
## UBA6 4.579279 5.242608 4.844744 4.871262 5.282477
## ESYT2 4.875324 5.136520 4.496599 4.397845 4.994216
## UHRF1BP1L 4.488927 3.614179 4.463849 4.480803 3.777839
## SHTN1 4.926983 4.752739 4.299910 5.145240 4.807961
## ILVBL 4.936206 4.395639 3.690728 4.480962 4.126668
## SH3PXD2B 5.335262 3.672522 2.516002 7.062948 5.140535
## X24.hr.rep.3
## UBA6 5.058791
## ESYT2 4.119505
## UHRF1BP1L 3.843625
## SHTN1 4.651524
## ILVBL 3.573552
## SH3PXD2B 3.916628
## Create a model matrix
Time <- as.factor(pData(eset)$Time)
Replicate <- as.factor(pData(eset)$Replicate)
(design <- model.matrix(~Replicate+Time))## (Intercept) Replicate2 Replicate3 Time24
## 1 1 0 0 0
## 2 1 1 0 0
## 3 1 0 1 0
## 4 1 0 0 1
## 5 1 1 0 1
## 6 1 0 1 1
## attr(,"assign")
## [1] 0 1 1 2
## attr(,"contrasts")
## attr(,"contrasts")$Replicate
## [1] "contr.treatment"
##
## attr(,"contrasts")$Time
## [1] "contr.treatment"
## Perform the fit
fit <- lmFit(data, design)
fit <- eBayes(fit)
## Get the results
res_t24 <- topTable(fit, coef = "Time24",
adjust.method="BH", number = Inf)
res_t24 <- addPlottingInfo(res_t24)
msnset_t24 <- addLimmaInfo(cmb, res_t24)
## Look at p-value distribution
hist(res_t24[, "P.Value"], breaks = 50,
main = "Histogram of p-values for 0/24hr LPS \n(limma's paired moderated t-test)",
xlab = "p-value")Figure 3.4: Histogram of raw p-values from differential analysis at 24 h post LPS
## save data as a TSV/CSV
write.csv(res_t24, file = "csv/limma_t24.csv")
write.exprs(msnset_t24, fDataCols = 131:138, sep = "\t",
file = "csv/timecourse_t24.tsv")It’s always a good idea to check the distribution of your raw uncorrected p-values. The easiest way to do this is to make a histogram of your p-values as per the above code chunk. This is a great post on how to interpret your p-values. We find we have a nice anti-conservative distribution.
The object res_24 is a data.frame containing the output from running topTable which is a function to extract a table of the top-ranked genes/proteins from the limma linear model fit.
We can now take this output and append it to our MSnSet and then plot the results. The classic way to present gene/protein expression data is a volcano plot.
The ggVolcano function plots the results on a volcano plot.
library("ggplot2")
library("dplyr")
library("ggrepel")
ggVolcano(res_t24, "24 hours", N = 20, lfc = 0.6, p = 0.01,
addLegend = TRUE, text.size = 12, base.text.size = 12,
legend.text.size = 12, geom.point.size = 2,
label.text.size = 4)Figure 3.5: Volcano plot showing up/downregulated proteins at 24 hours post LPS
3.4.2.2 12 hour timepoint
We repeat the analysis at each time point and look to see if we find any proteins that are significantly up- or downregulated.
## 0hr and 12hr
i <- grep("X0.hr", sampleNames(cmb))
j <- grep("X12.hr", sampleNames(cmb))
eset <- cmb[, c(i, j)]
data <- exprs(eset)
rownames(data) <- fData(cmb)[["GN"]]
head(data)## X0.hr.rep.1 X0.hr.rep.2 X0.hr.rep.3 X12.hr.rep.1 X12.hr.rep.2
## UBA6 4.579279 5.242608 4.844744 4.584263 5.190164
## ESYT2 4.875324 5.136520 4.496599 4.594140 5.180463
## UHRF1BP1L 4.488927 3.614179 4.463849 4.505748 3.814994
## SHTN1 4.926983 4.752739 4.299910 4.749325 4.655479
## ILVBL 4.936206 4.395639 3.690728 4.747260 4.037497
## SH3PXD2B 5.335262 3.672522 2.516002 6.088538 3.257607
## X12.hr.rep.3
## UBA6 4.634475
## ESYT2 4.501894
## UHRF1BP1L 4.022813
## SHTN1 4.252117
## ILVBL 3.502920
## SH3PXD2B 2.956236
## Create a model matrix
Time <- as.factor(pData(eset)$Time)
Replicate <- as.factor(pData(eset)$Replicate)
design <- model.matrix(~Replicate+Time)
## Perform the fit
fit <- lmFit(data, design)
fit <- eBayes(fit)
## Get the results
res_t12 <- topTable(fit, coef = "Time12",
adjust.method="BH", number = Inf)
res_t12 <- addPlottingInfo(res_t12)
msnset_t12 <- addLimmaInfo(cmb, res_t12)
## Look at p-value distribution
hist(res_t12[, "P.Value"], breaks = 50,
main = "Histogram of p-values for 0/12hr LPS \n(limma's paired moderated t-test)",
xlab = "p-value")Figure 3.6: Histogram of raw p-values from differential analysis at 12 h post LPS
## save data as a TSV/CSV
write.csv(res_t12, file = "csv/limma_t12.csv")
write.exprs(msnset_t12, fDataCols = 131:138, sep = "\t",
file = "csv/timecourse_t12.tsv")## plot volcanos
ggVolcano(res_t12, "12 hours", N = 20, lfc = 0.6,
p = 0.01, addLegend = FALSE,
text.size = 12, base.text.size = 12,
legend.text.size = 12, geom.point.size = 2,
label.text.size = 4)Figure 3.7: Volcano plot showing up/downregulated proteins at 12 hours post LPS
3.4.2.3 6 hour timepoint
## 0hr and 6r
i <- grep("X0.hr", sampleNames(cmb))
j <- grep("X6.hr", sampleNames(cmb))
eset <- cmb[, c(i, j)]
data <- exprs(eset)
rownames(data) <- fData(cmb)[["GN"]]
head(data)## X0.hr.rep.1 X0.hr.rep.2 X0.hr.rep.3 X6.hr.rep.1 X6.hr.rep.2
## UBA6 4.579279 5.242608 4.844744 4.478218 5.096956
## ESYT2 4.875324 5.136520 4.496599 4.913246 5.250985
## UHRF1BP1L 4.488927 3.614179 4.463849 4.546953 4.030109
## SHTN1 4.926983 4.752739 4.299910 4.968413 4.618690
## ILVBL 4.936206 4.395639 3.690728 4.783785 4.140193
## SH3PXD2B 5.335262 3.672522 2.516002 5.255045 3.250098
## X6.hr.rep.3
## UBA6 4.839907
## ESYT2 4.330492
## UHRF1BP1L 4.313316
## SHTN1 4.708527
## ILVBL 4.019145
## SH3PXD2B 2.282174
## Create a model matrix
Time <- as.factor(pData(eset)$Time)
Replicate <- as.factor(pData(eset)$Replicate)
design <- model.matrix(~Replicate+Time)
## Perform the fit
fit <- lmFit(data, design)
fit <- eBayes(fit)
## Get the results
res_t6 <- topTable(fit, coef = "Time6",
adjust.method="BH", number = Inf)
res_t6 <- addPlottingInfo(res_t6)
msnset_t6 <- addLimmaInfo(cmb, res_t6)
## Look at p-value distribution
hist(res_t6[, "P.Value"], breaks = 50,
main = "Histogram of p-values for 0/6hr LPS \n(limma's paired moderated t-test)",
xlab = "p-value")(#fig:dolimma_t6)Histogram of raw p-values from differential analysis at 6 h post LPS
## save data as a TSV/CSV
write.csv(res_t6, file = "csv/limma_t6.csv")
write.exprs(msnset_t6, fDataCols = 131:138, sep = "\t",
file = "csv/timecourse_t6.tsv")## plot volcanos
ggVolcano(res_t6, "6 hours", N = 20, lfc = 0.6,
p = 0.01, addLegend = FALSE,
text.size = 12, base.text.size = 12,
legend.text.size = 12, geom.point.size = 2,
label.text.size = 4)Figure 3.8: Volcano plot showing up/downregulated proteins at 6 hours post LPS
3.4.2.4 4 hour timepoint
## 0hr and 4hr
i <- grep("X0.hr", sampleNames(cmb))
j <- grep("X4.hr", sampleNames(cmb))
eset <- cmb[, c(i, j)]
data <- exprs(eset)
rownames(data) <- fData(cmb)[["GN"]]
head(data)## X0.hr.rep.1 X0.hr.rep.2 X0.hr.rep.3 X4.hr.rep.1 X4.hr.rep.2
## UBA6 4.579279 5.242608 4.844744 4.674778 5.360775
## ESYT2 4.875324 5.136520 4.496599 4.993125 5.268153
## UHRF1BP1L 4.488927 3.614179 4.463849 4.604388 3.659608
## SHTN1 4.926983 4.752739 4.299910 5.127168 4.831314
## ILVBL 4.936206 4.395639 3.690728 4.810118 4.155659
## SH3PXD2B 5.335262 3.672522 2.516002 5.334079 3.722221
## X4.hr.rep.3
## UBA6 4.844971
## ESYT2 4.744458
## UHRF1BP1L 4.296213
## SHTN1 4.886162
## ILVBL 3.649692
## SH3PXD2B 2.313917
## Create a model matrix
Time <- as.factor(pData(eset)$Time)
Replicate <- as.factor(pData(eset)$Replicate)
design <- model.matrix(~Replicate+Time)
## Perform the fit
fit <- lmFit(data, design)
fit <- eBayes(fit)
## Get the results
res_t4 <- topTable(fit, coef = "Time4",
adjust.method="BH", number = Inf)
res_t4 <- addPlottingInfo(res_t4)
msnset_t4 <- addLimmaInfo(cmb, res_t4)
## Look at p-value distribution
hist(res_t4[, "P.Value"], breaks = 50,
main = "Histogram of p-values for 0/4hr LPS \n(limma's paired moderated t-test)",
xlab = "p-value")(#fig:dolimma_t4)Histogram of raw p-values from differential analysis at 4 h post LPS
## save data as a TSV/CSV
write.csv(res_t4, file = "csv/limma_t4.csv")
write.exprs(msnset_t4, fDataCols = c(131:138), sep = "\t",
file = "csv/timecourse_t4.tsv")## plot volcanos
ggVolcano(res_t4, "4 hours", N = 20, lfc = 0.6,
p = 0.01, addLegend = FALSE,
text.size = 12, base.text.size = 12,
legend.text.size = 12, geom.point.size = 2,
label.text.size = 4)Figure 3.9: Volcano plot showing up/downregulated proteins at 4 hours post LPS
3.4.2.5 2 hour timepoint
## 0hr and 2hr
i <- grep("X0.hr", sampleNames(cmb))
j <- grep("X2.hr", sampleNames(cmb))
eset <- cmb[, c(i, j)]
data <- exprs(eset)
rownames(data) <- fData(cmb)[["GN"]]
head(data)## X0.hr.rep.1 X0.hr.rep.2 X0.hr.rep.3 X2.hr.rep.1 X2.hr.rep.2
## UBA6 4.579279 5.242608 4.844744 4.359477 5.190733
## ESYT2 4.875324 5.136520 4.496599 4.674483 5.146304
## UHRF1BP1L 4.488927 3.614179 4.463849 4.478383 3.873257
## SHTN1 4.926983 4.752739 4.299910 4.891723 4.652700
## ILVBL 4.936206 4.395639 3.690728 4.543970 4.174060
## SH3PXD2B 5.335262 3.672522 2.516002 5.101335 4.315416
## X2.hr.rep.3
## UBA6 4.691351
## ESYT2 4.753582
## UHRF1BP1L 4.712662
## SHTN1 4.917707
## ILVBL 3.817152
## SH3PXD2B 2.197979
## Create a model matrix
Time <- as.factor(pData(eset)$Time)
Replicate <- as.factor(pData(eset)$Replicate)
design <- model.matrix(~Replicate+Time)
## Perform the fit
fit <- lmFit(data, design)
fit <- eBayes(fit)
## Get the results
res_t2 <- topTable(fit, coef = "Time2",
adjust.method="BH", number = Inf)
res_t2 <- addPlottingInfo(res_t2)
msnset_t2 <- addLimmaInfo(cmb, res_t2)
## Look at p-value distribution
hist(res_t2[, "P.Value"], breaks = 50,
main = "Histogram of p-values for 0/2hr LPS \n(limma's paired moderated t-test)",
xlab = "p-value")(#fig:dolimma_t2)Histogram of raw p-values from differential analysis at 2 h post LPS
## save data as a TSV/CSV
write.csv(res_t2, file = "csv/limma_t2.csv")
write.exprs(msnset_t4, fDataCols = c(131:138), sep = "\t",
file = "csv/timecourse_t2.tsv")## plot volcanos
ggVolcano(res_t2, "2 hours", N = 20, lfc = 0.6,
p = 0.05, addLegend = FALSE,
text.size = 12, base.text.size = 12,
legend.text.size = 12, geom.point.size = 2,
label.text.size = 4)Figure 3.10: Volcano plot showing up/downregulated proteins at 2 hours post LPS
3.4.3 Summary
A total of 311 proteins were found to be altered in abundance during the time course of LPS stimulation, with statistical significance (adjusted p-value < 0.01 and log2FC > 0.6) (Supplementary Table 1 of2). We do not discuss the functional effects of these changes in detail in this workflow and instead we refer readers to the Mulvey et al 2021.
3.5 Bayesian temporal clustering
Bayesian correlated clustering was conducted on the shotgun proteomic time-course series to capture clusters of co-regulated proteins and temporal patterns of protein expression in response to LPS. Replicate experiments were combined using multiple dataset integration MDI7 where the number of clusters were automatically inferred.
Bayesian inference was performed using Markov-chain Monte Carlo (MCMC) as implemented in the MDI-GPU software.7 Clusters were extracted only for proteins that were consistently allocated to the same clusterings (sampled from the posterior distribution) across replicates (the results can be found in Supplementary Table 3 of Mulvey et al. and also in the csv directory of this Git repo).
In the below code chunk we load the results from temporal clustering and plot 12 clusters of interest as discussed in Mulvey et al. (Figure 2 of2)
library("RColorBrewer")
source("r/plotRibbons.R")
## Read in MDI clustering results
mdi_rep1 <- read.csv("csv/mdi_clustering_lpsrep1.csv")
mdi_rep2 <- read.csv("csv/mdi_clustering_lpsrep2.csv")
mdi_rep3 <- read.csv("csv/mdi_clustering_lpsrep3.csv")
mdi <- read.csv("csv/mdi_clusters_output.csv")
# get median normalised intensity
dat_mat <- list(data.matrix(mdi_rep1[, -1]),
data.matrix(mdi_rep2[, -1]),
data.matrix(mdi_rep3[, -1]))
av_mat <- apply(simplify2array(dat_mat), c(1,2), median)
rownames(av_mat) <- mdi_rep1[,1]
colnames(av_mat) <- c(0, 2, 4, 6, 12, 24)
head(av_mat)## 0 2 4 6 12 24
## P02795 -1.0406225 -0.8355461 -0.6604120 0.13893606 1.0759237 1.258747
## P04179 -0.6899927 -0.6821170 -0.5093226 -0.30338106 0.1302568 1.952588
## O14879 -0.8874299 -0.8758429 -0.5680529 -0.01642289 0.6585623 1.661210
## Q9BYX4 -0.8292398 -0.8356126 -0.6969017 -0.08215123 0.9237005 1.515785
## P00973 -0.8814504 -0.8015016 -0.6501797 -0.11263572 0.8438697 1.578594
## P05362 -0.8188745 -0.7149888 -0.4673084 -0.22529338 0.5581240 1.756882
## plot clusters of interest
ids <- c(1:6, 9:11, 13, 14, 17)
mdi_profs <- sapply(ids, function(z)
av_mat[mdi$Protein.Accession[which(mdi$Cluster.Number == z)], ])
names(mdi_profs) <- paste0("cluster", ids)
## pick a good palette
ribbonCol <- c(brewer.pal(n = 9, "Oranges")[-c(1:3)],
brewer.pal(n = 9, "GnBu")[-c(1:3)])
par(mfrow = c(3,2), mar = c(6, 5, 3, 3))
for (i in 1:6) {
ribbonPlot(mdi_profs[[i]], col = ribbonCol[i], c(0.05, .95),
main = paste("Cluster", ids[i]), cex.main = 2, size = 2)
}Figure 3.11: Temporal abundance profiles 6 clusters output from the MDI clustering analysis that showed a pattern of upregulation over time.
par(mfrow = c(3,2), mar = c(6, 5, 3, 3))
for (i in 7:12) {
ribbonPlot(mdi_profs[[i]], col = ribbonCol[i], c(0.05, .95),
main = paste("Cluster", ids[i]), cex.main = 2, size = 2)
}Figure 3.12: Temporal abundance profiles 6 clusters output from the MDI clustering analysis that showed a pattern of downregulation over time.
3.6 Gene Ontology enrichment
Temporal clusters were functionally annotated by using the Gene Ontology (GO).8 For each cluster output from the Bayesian temporal clustering, in turn, an enrichment test for biological process (BP), cellular component (CC) and molecular function (MF) annotations, was carried out using the Database for Annotation, Visualisation and Integrated Discovery (DAVID v6.8; https://david.ncifcrf.gov/) where a cutoff of < 0.05 was applied according to the Benjamini-Hochberg procedure.9 The GO annotation enrichment results are found in Supplementary Table 4 of Mulvey et al 2021.
In the below code chunk some of the results from the GO enrichment (Figure 3 of Mulvey et al. 2021). GOCC, GOMF and GOBP annotation term enrichment for the the clusters are shown below where the -log10(adjusted p-value) is shown along the x-axis and most highly enriched term along the y-axis. The numbers within each barplot refer to the number of proteins associated with the term in each cluster.
## use custom code for bar plot figures
## https://github.com/CambridgeCentreForProteomics/thp-lopit-2021/blob/main/R/GObarplot.R
source("r/GObarplot.R")
GObarplots(filename = "csv/david_data_gobp.csv", cols = ribbonCol, N = 30) +
ggtitle("GO Biological Process Terms")Figure 3.13: Gene Ontology molecular function enrichment results for 12 clusters of interest output from the MDI analysis. The numbers within each barchart refer to the number of proteins associated with the term in that cluster.
GObarplots(filename = "csv/david_data_gocc.csv", cols = ribbonCol) +
ggtitle("GO Cellular Component Terms")Figure 3.14: Gene Ontology cellular component enrichment results for 12 clusters of interest output from the MDI analysis. The numbers within each barchart refer to the number of proteins associated with the term in that cluster.
GObarplots(filename = "csv/david_data_gomf.csv", cols = ribbonCol, N = 15) +
ggtitle("GO Molecular Function Terms")Figure 3.15: Gene Ontology molecular function enrichment results for 12 clusters of interest output from the MDI analysis. The numbers within each barchart refer to the number of proteins associated with the term in that cluster.
The timecourse of LPS provides an insight into the protein expression of THP-1 proteome during the initial phases of a pro-inflammatory response. In order the gain a complete picture of protein relocalisation events we performed a series of hyperLOPIT experiments and 0 and 12 hour LPS time-points to give a deeper spaial understanding of the dynamic changes that occur in the proteome following stimulation.
4 Spatial proteomics data analysis
4.1 The hyperLOPIT workflow
Using the hyperLOPIT proteomics platform10 we obtained spatial maps that capture the steady-state distribution of thousands of proteins in the THP-1 human leukaemia cell line. Experiments were conducted in triplicate and the samples were analysed and collected when cells were (1) unstimulated and then (2) at 12 hours following stimulation with LPS.
The hyperLOPIT method combines biochemical cell fractionation with multiplexed high-resolution mass-spectrometry,10 the full protocol and experimental design can be found in.2 Briefly, TMT labelling was conducted as described in11 and 20 fractions including the cytosol-enriched fraction were labelled per gradient, by combining two TMT 10-plex experiments in an interleaved labelling design to capture as much subcellular diversity as possible. The experimental design for each dataset is stored in the pData slot of each dataset.
To access the full experimental design use the pData function
## Tag Treatment Replicate Set Fraction
## unstim_rep1_set1_126_cyto 126 Unstimulated 1 1 cyto
## unstim_rep2_set1_126_cyto 126 Unstimulated 2 1 cyto
## unstim_rep3_set1_126_cyto 126 Unstimulated 3 1 cyto
## unstim_rep1_set1_127N_F1.4 127N Unstimulated 1 1 F1.4
## unstim_rep2_set1_127N_F1.6 127N Unstimulated 2 1 F1.6
## unstim_rep3_set1_127N_F1.6 127N Unstimulated 3 1 F1.6
## unstim_rep1_set2_126_F5.6 126 Unstimulated 1 2 F5.6
## unstim_rep1_set1_127C_F7 127C Unstimulated 1 1 F7
## unstim_rep2_set2_127N_F7.8 127N Unstimulated 2 2 F7.8
## unstim_rep3_set2_126_F7.8 126 Unstimulated 3 2 F7.8
## unstim_rep1_set2_127N_F8 127N Unstimulated 1 2 F8
## unstim_rep1_set1_128N_F9 128N Unstimulated 1 1 F9
## unstim_rep3_set1_127C_F9 127C Unstimulated 3 1 F9
## unstim_rep2_set1_127C_F9.10 127C Unstimulated 2 1 F9.10
## unstim_rep1_set2_127C_F10 127C Unstimulated 1 2 F10
## unstim_rep3_set2_127N_F10 127N Unstimulated 3 2 F10
## unstim_rep1_set1_128C_F11 128C Unstimulated 1 1 F11
## unstim_rep3_set1_128N_F11 128N Unstimulated 3 1 F11
## unstim_rep2_set2_127C_F11.12 127C Unstimulated 2 2 F11.12
## unstim_rep1_set2_128N_F12 128N Unstimulated 1 2 F12
## unstim_rep2_set1_128N_F12 128N Unstimulated 2 1 F12
## unstim_rep3_set2_127C_F12 127C Unstimulated 3 2 F12
## unstim_rep1_set1_129N_F13 129N Unstimulated 1 1 F13
## unsti_rep2_set2_128N_F13 128N Unstimulated 2 2 F13
## unstim_rep3_set1_128C_F13 128C Unstimulated 3 1 F13
## unstim_rep1_set2_128C_F14 128C Unstimulated 1 2 F14
## unstim_rep2_set1_128C_F14 128C Unstimulated 2 1 F14
## unstim_rep3_set2_128N_F14 128N Unstimulated 3 2 F14
## unstim_rep1_set1_129C_F15 129C Unstimulated 1 1 F15
## unstim_rep2_set2_128C_F15 128C Unstimulated 2 2 F15
## unstim_rep3_set1_129N_F15 129N Unstimulated 3 1 F15
## unstim_rep1_set2_129N_F16 129N Unstimulated 1 2 F16
## unstim_rep2_set1_129N_F16 129N Unstimulated 2 1 F16
## unstim_rep3_set2_128C_F16 128C Unstimulated 3 2 F16
## unstim_rep1_set1_130N_F17 130N Unstimulated 1 1 F17
## unstim_rep2_set2_129N_F17 129N Unstimulated 2 2 F17
## unstim_rep3_set1_129C_F17 129C Unstimulated 3 1 F17
## unstim_rep1_set2_129C_F18 129C Unstimulated 1 2 F18
## unstim_rep2_set1_129C_F18 129C Unstimulated 2 1 F18
## unstim_rep3_set2_129N_F18 129N Unstimulated 3 2 F18
## unstim_rep1_set1_130C_F19 130C Unstimulated 1 1 F19
## unstim_rep2_set2_129C_F19 129C Unstimulated 2 2 F19
## unstim_rep3_set1_130N_F19 130N Unstimulated 3 1 F19
## unstim_rep1_set2_130N_F20 130N Unstimulated 1 2 F20
## unstim_rep2_set1_130N_F20 130N Unstimulated 2 1 F20
## unstim_rep3_set2_129C_F20 129C Unstimulated 3 2 F20
## unstim_rep1_set1_131_F21 131 Unstimulated 1 1 F21
## unstim_rep2_set2_130N_F21 130N Unstimulated 2 2 F21
## unstim_rep3_set1_130C_F21 130C Unstimulated 3 1 F21
## unstim_rep1_set2_130C_F22 130C Unstimulated 1 2 F22
## unstim_rep2_set1_130C_F22 130C Unstimulated 2 1 F22
## unstim_rep3_set2_130N_F22 130N Unstimulated 3 2 F22
## unstim_rep2_set2_130C_F23 130C Unstimulated 2 2 F23
## unstim_rep3_set1_131_F23 131 Unstimulated 3 1 F23
## unstim_rep1_set2_131_F24 131 Unstimulated 1 2 F24
## unstim_rep2_set1_131_F24 131 Unstimulated 2 1 F24
## unstim_rep3_set2_130C_F24 130C Unstimulated 3 2 F24
## unstim_rep2_set2_131_F25 131 Unstimulated 2 2 F25
## unstim_rep3_set2_131_F26 131 Unstimulated 3 2 F26
## Tag Treatment Replicate Set Fraction
## lps_rep1_set1_126_cyto 126 LPS 1 1 cyto
## lps_rep2_set1_126_cyto 126 LPS 2 1 cyto
## lps_rep3_set1_126_cyto 126 LPS 3 1 cyto
## lps_rep1_set1_127N_F1.4 127N LPS 1 1 F1.4
## lps_rep2_set1_127N_F1.6 127N LPS 2 1 F1.6
## lps_rep3_set1_127N_F1.6 127N LPS 3 1 F1.6
## lps_rep1_set2_126_F5.7 126 LPS 1 2 F5.7
## lps_rep2_set2_126_F7.8 126 LPS 2 2 F7.8
## lps_rep3_set2_126_F7.8 126 LPS 3 2 F7.8
## lps_rep1_set1_127C_F8 127C LPS 1 1 F8
## lps_rep1_set2_127N_F9 127N LPS 1 2 F9
## lps_rep3_set1_127C_F9 127C LPS 3 1 F9
## lps_rep2_set1_127C_F9.10 127C LPS 2 1 F9.10
## lps_rep1_set1_128N_F10 128N LPS 1 1 F10
## lps_rep3_set2_127N_F10 127N LPS 3 2 F10
## lps_rep1_set2_127C_F11 127C LPS 1 2 F11
## lps_rep2_set2_127N_F11 127N LPS 2 2 F11
## lps_rep3_set1_128N_F11 128N LPS 3 1 F11
## lps_rep1_set1_128C_F12 128C LPS 1 1 F12
## lps_rep2_set1_128N_F12 128N LPS 2 1 F12
## lps_rep3_set2_127C_F12 127C LPS 3 2 F12
## lps_rep1_set2_128N_F13 128N LPS 1 2 F13
## lps_rep2_set2_127C_F13 127C LPS 2 2 F13
## lps_rep3_set1_128C_F13 128C LPS 3 1 F13
## lps_rep1_set1_129N_F14 129N LPS 1 1 F14
## lps_rep2_set1_128C_F14 128C LPS 2 1 F14
## lps_rep3_set2_128N_F14 128N LPS 3 2 F14
## lps_rep1_set2_128C_F15 128C LPS 1 2 F15
## lps_rep2_set2_128N_F15 128N LPS 2 2 F15
## lps_rep3_set1_129N_F15 129N LPS 3 1 F15
## lps_rep1_set1_129C_F16 129C LPS 1 1 F16
## lps_rep2_set1_129N_F16 129N LPS 2 1 F16
## lps_rep3_set2_128C_F16 128C LPS 3 2 F16
## lps_rep1_set2_129N_F17 129N LPS 1 2 F17
## lps_rep2_set2_128C_F17 128C LPS 2 2 F17
## lps_rep3_set1_129C_F17 129C LPS 3 1 F17
## lps_rep1_set1_130N_F18 130N LPS 1 1 F18
## lps_rep2_set1_129C_F18 129C LPS 2 1 F18
## lps_rep3_set2_129N_F18 129N LPS 3 2 F18
## lps_rep1_set2_129C_F19 129C LPS 1 2 F19
## lps_rep2_set2_129N_F19 129N LPS 2 2 F19
## lps_rep3_set1_130N_F19 130N LPS 3 1 F19
## lps_rep1_set1_130C_F20 130C LPS 1 1 F20
## lps_rep2_set1_130N_F20 130N LPS 2 1 F20
## lps_rep3_set2_129C_F20 129C LPS 3 2 F20
## lps_rep1_set2_130N_F21 130N LPS 1 2 F21
## lps_rep2_set2_129C_F21 129C LPS 2 2 F21
## lps_rep3_set1_130C_F21 130C LPS 3 1 F21
## lps_rep1_set1_131_F22 131 LPS 1 1 F22
## lps_rep2_set1_130C_F22 130C LPS 2 1 F22
## lps_rep3_set2_130N_F22 130N LPS 3 2 F22
## lps_rep1_set2_130C_F23 130C LPS 1 2 F23
## lps_rep2_set2_130N_F23 130N LPS 2 2 F23
## lps_rep3_set1_131_F23 131 LPS 3 1 F23
## lps_rep2_set1_131_F24 131 LPS 2 1 F24
## lps_rep3_set2_130C_F24 130C LPS 3 2 F24
## lps_rep1_set2_131_F25 131 LPS 1 2 F25
## lps_rep2_set2_130C_F25 130C LPS 2 2 F25
## lps_rep3_set2_131_F26 131 LPS 3 2 F26
As described in11 the data was processed with Proteome Discoverer v2.1 (Thermo Fisher Scientific) and Mascot server v2.3.02 (Matrix Science) using the SwissProt sequence database for Homo sapiens (www.uniprot.org in November 2016) and the cRAP database (common Repository for Adventitious Proteins, https://www.thegpm.org/crap). Standard filtering of the raw data was conducted as per11 to remove contaminants and low abundant PSMs. A maximum of two missing values per TMT experiment was allowed and the data was directly exported from Proteome Discoverer at the PSM level for downstream analysis in R.
The experiments were done in triplicate for each condition and each replicate contains 2 x TMT 10-plex sets (which we denote as “set 1” and “set 2”). Thus, in total we conducted a total of 12 experiments, 6 per condition wherein we had 2 sets per replicate containing a total of 20 fractions/channels per replicate. One TMT channel was removed (TMT tag 126 in replicate 2, set 2 in the unstimulated) due to erroneous labelling of insoluble material during the sample preparation for this specific tag. The “Average Reporter S/N” value was recalculated for the nine remaining channels in the corresponding 10plex set and PSMs with a value less than 9.0 were discarded (please see Data Processing in the Supplementary Information of2).
4.2 PSM level data processing
4.2.1 Missing values assessment
The 12 PSM level datasets were imported into R and missing values were carefully assessed.
Load the PSM level unstimulated data,
## Unstimulated data
data("psms_thpLOPIT_unstim_rep1_set1")
data("psms_thpLOPIT_unstim_rep1_set2")
data("psms_thpLOPIT_unstim_rep2_set1")
data("psms_thpLOPIT_unstim_rep2_set2")
data("psms_thpLOPIT_unstim_rep3_set1")
data("psms_thpLOPIT_unstim_rep3_set2")Load the PSM level 12h-LPS stimulated data,
## 12h post LPS-stimulated
data("psms_thpLOPIT_lps_rep1_set1")
data("psms_thpLOPIT_lps_rep1_set2")
data("psms_thpLOPIT_lps_rep2_set1")
data("psms_thpLOPIT_lps_rep2_set2")
data("psms_thpLOPIT_lps_rep3_set1")
data("psms_thpLOPIT_lps_rep3_set2")For ease of coding we create a list of MSnSets for each condition
psms <- MSnSetList(
list(
psms_thpLOPIT_unstim_rep1_set1,
psms_thpLOPIT_unstim_rep1_set2,
psms_thpLOPIT_unstim_rep2_set1,
psms_thpLOPIT_unstim_rep2_set2,
psms_thpLOPIT_unstim_rep3_set1,
psms_thpLOPIT_unstim_rep3_set2,
psms_thpLOPIT_lps_rep1_set1,
psms_thpLOPIT_lps_rep1_set2,
psms_thpLOPIT_lps_rep2_set1,
psms_thpLOPIT_lps_rep2_set2,
psms_thpLOPIT_lps_rep3_set1,
psms_thpLOPIT_lps_rep3_set2
)
)
## add list names for each dataset
.nams <- paste0("Rep", rep(1:3, each = 2), "_set", rep(1:2, 3))
names(psms) <- c(paste0(.nams, "_unstim"), paste0(.nams, "_lps"))We can view the number of PSMs per experiment,
## Rep1_set1_unstim Rep1_set2_unstim Rep2_set1_unstim Rep2_set2_unstim
## 44137 41860 39297 37919
## Rep3_set1_unstim Rep3_set2_unstim Rep1_set1_lps Rep1_set2_lps
## 48199 44802 40994 63844
## Rep2_set1_lps Rep2_set2_lps Rep3_set1_lps Rep3_set2_lps
## 43799 44055 46805 45600
If we examine the corresponding protein group of each PSM with a missing value, we find that there are other PSMs available for quantitation for the majority of proteins. There are still several hundred cases where we only have 1 PSM for a given protein group, so we would lose several hundred proteins per replicate if we were to just remove these PSMs. We assess the missing values across all experiments using the naPlot function to see if there is a trend in where missing values occur.
Generate naPlots,
for (i in seq(psms)) {
par(las = 2, oma = c(10, 1, 1, 1))
naplot(psms[[i]], col = "black", las = 2, reorderColumns = FALSE,
main = names(psms)[i], cex.axis = 2)
}Figure 4.1: Heatmaps showing missing value distributions per set and replciate
The above naPlots show that missing values tend to accumulate at the end of the gradient, and more specifically in the first few fractions of the gradient of each experiment, which classically reflect the gradient distribution e.g. PSMs that are often highly mitochondrial have a huge signal in the heavy channels but little elsewhere in the gradient and thus can result in missing values in the other channels. It is also common to find biologically relevant missing values such as those resulting from the absence of the low abundance of ions. As values do not appear to be missing at random we use a left-censored deterministic minimal value approach, MinDet in MSnbase.
PSMs were quality controlled post-imputation and then combined to protein level by calculating the median of all PSM intensities corresponding to the leading Uniprot Accession number for each protein group.
4.2.2 Data normalisation
Following the standard pRoloc workflow12 PSMs are scaled into the same intensity interval by dividing each intensity by the sum of the intensities for that quantitative feature. This transformation of the data assures cancellation of the effect of the absolute intensities of the quantitative features along the rows, and focuses subsequent analyses on the relative profiles along the sub-cellular channels. This is important for spatial proteomic experiments are proteins that co-localise in a cell are known to exhibit similar quantitative profiles across the gradient fractions employed.13
4.2.3 Aggregation to protein
We use all available PSMs for quantification and aggregate PSMs to proteins using the combineFeatures function in MSnbase by calculating the median of all PSM intensities corresponding to the leading Uniprot Accession number for each protein group.
prots <- lapply(psms.imputed.norm, function(z)
combineFeatures(z, method = "median",
groupBy = fData(z)[, "Master.Protein.Accessions"]))
## become combining all protein sets we tidy up the feature labels of the dataset
ll <- paste0(rep(c("unst", "lps"), 1, each = 6), ".r",
rep(1:3, 1, each = 2), ".s", 1:2)
for (i in seq(prots)) {
prots@x[[i]] <- updateFvarLabels(prots[[i]], label = ll[i], sep = "_")
}
## combine TMT sets and examine each replicate for each condition
unst_r1 <- filterNA(MSnbase::combine(prots[[1]], prots[[2]]))
unst_r2 <- filterNA(MSnbase::combine(prots[[3]], prots[[4]]))
unst_r3 <- filterNA(MSnbase::combine(prots[[5]], prots[[6]]))
lps_r1 <- filterNA(MSnbase::combine(prots[[7]], prots[[8]]))
lps_r2 <- filterNA(MSnbase::combine(prots[[9]], prots[[10]]))
lps_r3 <- filterNA(MSnbase::combine(prots[[11]], prots[[12]]))
tot_prots <- data.frame("Unstimulated" = c(`Replicate 1` = nrow(unst_r1),
`Replicate 2` = nrow(unst_r2),
`Replicate 3`= nrow(unst_r3)),
"LPS" = c(`Replicate 1` = nrow(lps_r1),
`Replicate 2` = nrow(lps_r2),
`Replicate 3` = nrow(lps_r3)))library("knitr")
library("kableExtra")
kable(tot_prots, caption = "Number of quantified proteins per replicate per condition")| Unstimulated | LPS | |
|---|---|---|
| Replicate 1 | 5107 | 4879 |
| Replicate 2 | 4838 | 4866 |
| Replicate 3 | 5733 | 5848 |
4.3 Protein level data processing
As shown in the above section we quantify between ~4800-5800 proteins per replicate. The below Venn diagrams show the overlap between replicates within conditions. We find 3882 proteins common in the unstimulated hyperLOPIT experiment and 4067 in the 12h-LPS stimulated hyperLOPIT experiment.
We use the VennDiagram package.
## Load R packages required for generating Venn diagrams
library("VennDiagram")
library("scales")
library("ggplot2")
## HL unstimulated
venn.diagram(
x = list(featureNames(unst_r1),
featureNames(unst_r2),
featureNames(unst_r3)),
category.names = c("Replicate 1" , "Replicate 2 " , "Replicate 3"),
filename = "figures/venn_HL_unst_replicates.png",
main = "hyperLOPIT: Untreated THP-1 cells",
col=c("#440154ff", '#21908dff', '#D6BA0D'),
fill = c(alpha("#440154ff",0.3), alpha('#21908dff',0.3), alpha('#D6BA0D',0.3)),
fontfamily = "sans",
cat.fontfamily = "sans",
main.fontfamily = "sans",
cat.col = c("#440154ff", '#21908dff', '#D6BA0D'),
cat.cex = 1.2,
main.cex = 1.6,
cex = 1.7,
cat.fontface = 2,
cat.dist = c(0.07, 0.07, 0.03),
sub = "",
output = FALSE
)
# HL LPS
venn.diagram(
x = list(featureNames(lps_r1),
featureNames(lps_r2),
featureNames(lps_r3)),
category.names = c("Replicate 1" , "Replicate 2 " , "Replicate 3"),
filename = "figures/venn_HL_lps_replicates.png",
main = "hyperLOPIT: 12h-LPS stimulated THP-1 cells",
col=c("#440154ff", '#21908dff', '#D6BA0D'),
fill = c(alpha("#440154ff",0.3), alpha('#21908dff',0.3), alpha('#D6BA0D',0.3)),
fontfamily = "sans",
cat.fontfamily = "sans",
main.fontfamily = "sans",
cat.col = c("#440154ff", '#21908dff', '#D6BA0D'),
cat.cex = 1.2,
main.cex = 1.6,
cex = 1.7,
cat.fontface = 2,
cat.dist = c(0.07, 0.07, 0.03),
sub = "",
output = FALSE
)Figure 4.2: Overlap of protein groups identified between replicated experiments
4.4 Dataset concatenation
We use the combine function in MSnbase to perform data fusion (concatenation) within each condition to maximise subcellular resolution and thus the reliability in protein classification [as per the pRoloc pipeline.10 Trotter et al. 14 have shown a significant improvement in classifier accuracy when combining replicated experiments in spatial proteomics. Specifically, we concatenate all gradient fractions across replicated experiments to give better discrimination between subcellular niches (as shown in10) which gives users the opportunity to resolve niches that may not have been discovered when examining replicates alone.
We note (as explained in12) that direct comparisons of individual TMT channels in replicated experiments do not provide an adequate, goal-driven assessment of different experiments due to the nature of the gradient fraction collection, where quantitative channels do not correspond to identical selected fractions along the gradient.
Concatenate replicates for each condition,
## combine replicates for each condition
unst_full <- filterNA(MSnbase::combine(unst_r1, unst_r2))
unst_full <- filterNA(MSnbase::combine(unst_full, unst_r3))
lps_full <- filterNA(MSnbase::combine(lps_r1, lps_r2))
lps_full <- filterNA(MSnbase::combine(lps_full, lps_r3)) # HL intersect
venn.diagram(
x = list(featureNames(unst_full),
featureNames(lps_full)),
rotation.degree = 180,
category.names = c("12h-LPS\nstimulated", "Untreated"),
filename = "figures/venn_HL_conditions.png",
main = "Subset for common proteins:\nhyperLOPIT conditions",
col=c("#440154ff", '#21908dff'),
fill = c(alpha("#440154ff",0.3), alpha('#21908dff',0.3)),
fontfamily = "sans",
cat.fontfamily = "sans",
main.fontfamily = "sans",
cat.col = c('#21908dff', "#440154ff"),
margin = 0.05,
cat.pos = c(-130, 132),
cat.dist = c(0.1, 0.09),
cat.cex = 1.2,
main.cex = 1.6,
cex = 1.7,
cat.fontface = 2,
sub = "",
)Figure 4.3: Overlap of protein groups identified in both conditions
We find 3288 proteins common all 12 experiments. In the next code chunk we subset our data to keep only proteins common between all experiments.
4.4.1 Final hyperLOPIT datasets for downstream analysis
Subset for common proteins in all replicates and all conditions,
4.4.2 Adding marker proteins
A list of 783 annotated, unambiguous resident organelle marker proteins from 11 subcellular niches: mitochondria, ER, Golgi apparatus, lysosome, peroxisome, PM, nucleus, nucleolus, chromatin, ribosome and cytosol, were curated from The Uniprot database, Gene Ontology8 and from careful mining of the literature. Only proteins known to localise to a single location were included as markers.
We use the addMarkers function in pRoloc to annotate our two datasets from this list of markers (found in the csv directory of this repository). The marker list can also be extracted from pRolocdata by using the getMarkers function with any of the THP datasets.
Adding markers,
## Markers in data: 783 out of 3288
## organelleMarkers
## 40S/60S Ribosome Chromatin Cytosol
## 75 73 52
## Endoplasmic Reticulum Golgi Apparatus Lysosome
## 69 39 49
## Mitochondria Nucleolus Nucleus
## 197 38 91
## Peroxisome Plasma Membrane unknown
## 29 71 2505
## Markers in data: 783 out of 3288
## organelleMarkers
## 40S/60S Ribosome Chromatin Cytosol
## 75 73 52
## Endoplasmic Reticulum Golgi Apparatus Lysosome
## 69 39 49
## Mitochondria Nucleolus Nucleus
## 197 38 91
## Peroxisome Plasma Membrane unknown
## 29 71 2505
4.4.3 Visualising the data
We use t-Distributed Stochastic Neighbor Embedding (t-SNE) to project our 60 dimension data into two-dimensions to visualise organelle separation.
In the below code chunk we plot the data and highlight the subcellular markers on each dataset (Figure 4 of2). Each point represents one protein. Markers are highlighted by different colours as denoted by the key and proteins for the subcellular location is unknown or undefined are grey.
source("r/prettymap.R")
## set organelle colours
mycol <- c("#88CCEE", "#332288", "#53CAB7", "#0170b4", "#204f20", "#990000",
"#E69F00", "#DDCC77", "#E18493", "#AA4499", "#D55E00")
setStockcol(mycol)
setUnknownpch(16)
## Generate the t-SNE coords (Figure 4 of [1])
set.seed(399)
tsne_unst <- plot2D(unst, method = "t-SNE", plot = FALSE)
set.seed(399)
tsne_lps <- plot2D(lps, method = "t-SNE", plot = FALSE)
## plot the data as t-SNE maps
par(mfrow = c(2, 2))
oo = c(1:3, 10, 5, 4, 6:7, 9, 8, 11)
myleg <- c(getMarkerClasses(unst), "Unknown")
prettyTSNE(tsne_unst, unst, fcol = "markers",
main = "Subcellular markers\nunstimulated THP1-cells",
orgOrder = oo, mainCol = mycol, outlineCol = darken(mycol))
prettyTSNE(tsne_lps, lps,
main = "Subcellular markers\n12h-LPS stimulated THP1-cells",
orgOrder = oo, mainCol = mycol, outlineCol = darken(mycol))
## add a legend
plot(NULL, xaxt='n',yaxt='n',bty='n',ylab='',xlab='', xlim=0:1, ylim=0:1)
legend("topleft", legend = myleg, col = mycol, bty = "n",
pch = 19, cex = 1.2, pt.cex = 1.6, ncol = 2)Figure 4.4: t-SNE plots of the (concatenated) LOPIT datasets for each condition (Figure 4 of Mulvey et al. 2021)
4.5 Classification using a Bayesian framework
Proteins are assigned to one of the 11 subcellular marker classes using TAGM-MCMC.15 TAGM-MCMC is a semi-supervised Bayesian generative classifier based on a T-Augmented Gaussian Mixture model that uses Bayesian computation performed using Markov-chain Monte Carlo. It is one of the many supervised machine learning methods available in the pRoloc package, but currently the only Bayesian method that is available in the package for the prediction of subcellular location for spatial proteomics data.
The advantage of using TAGM, and Bayesian methods in general, over classic supervised machine learning approaches is the ability for the algorithm to quantify the localisation uncertainty. The TAGM classifier models each annotated subcellular class using a Gaussian distribution and thus the full dataset can be modelled as a mixture of Gaussians. As described in15 an outlier component probability is also included in this model which is mathematically described as a multivariate student’s t-distribution which gives extra information regarding the
Full details of the TAGM Bayesian methodology and mathematics are found in15 and a detailed Bioconductor workflow for Bayesian analysis of spatial proteomoics data can be found in.16 We follow this workflow for the analysis used here.
4.5.1 Training
Following Crook et al16 we take the concatenated datasets for each conditions and run the TAGM-MCMC workflow. A collapsed Gibbs sampler was run in parallel for 9 chains to sample from the posterior distributions of localisation probabilites, with each chain run for 25,000 iterations and the Gelman-Rubin’s diagnostic was used to assess the convergence of the 9 Markov-Chains and the 3 best chains were kept and pooled for data processing for each condition.
In the code chunk below we show how to run the tagmMcmcTrain function to generate the samples from the posterior distributions of each dataset (note: we do not run this dynamically as running is computationally intensive. We suggest you use a cluster or HPC if you have one available and scale according to the cores and numChains used)
## Load the coda library for calculating the Gelman diagnostics
library("coda")
## Train TAGM-MCMC
p_lps <- tagmMcmcTrain(object = lps,
numIter = 25000,
burnin = 5000,
thin = 10,
numChains = 9)
p_unst <- tagmMcmcTrain(object = unst,
numIter = 25000,
burnin = 5000,
thin = 10,
numChains = 9)
## All chains look good and all oscillate around an average of 490 outliers
out_unst <- mcmc_get_outliers(p_unst)
out_lps <- mcmc_get_outliers(p_lps)
## Calculate Gelman's Diagnostic
gelman.diag(out_unst)
gelman.diag(out_lps)
# check all pairs as per the f1000 vignette [10]
gelman.diag(out_unst[1:2])
gelman.diag(out_unst[1:3]) # etc...Following the TAGM workflow16 we examine the chains for convergence and indeed find all chains look good and oscillate around and average of 490 outliers. We calculate the Gelman and Rubin Diagnostic17 for a more rigorous and unbiased analysis of convergence. This statistic is often referred to as R̂ or the potential scale reduction factor and Geman and Rubin suggest that chains with a R̂ < 1.2 are likely to have converged. We find all to be < 1.2. We pick the 5 best chains for each dataset which yields the lowest upper confidence interval (as per15). These are then passed to mcmc_pool_chains and tagmMcmcProcess where the the summary slot of the MCMCParams object is populated with basic summaries of the MCMCChains, such as allocations and localisation probabilities.
mcmc_unst_pooled <- mcmc_pool_chains(mcmc_unst)
mcmc_lps_pooled <- mcmc_pool_chains(mcmc_lps)
mcmc_unst_pooled <- tagmMcmcProcess(mcmc_unst_pooled)
mcmc_lps_pooled <- tagmMcmcProcess(mcmc_lps_pooled)
summary(mcmc_unst_pooled@summary@posteriorEstimates)
summary(mcmc_unst_pooled@summary@tagm.joint)
summary(mcmc_lps_pooled@summary@posteriorEstimates)
summary(mcmc_lps_pooled@summary@tagm.joint)
mcmc_lps <- mcmc_lps_pooled
mcmc_unst <- mcmc_unst_pooled4.5.2 Prediction
Finally, we use the tagmMcmcPredict function to obtain the full probability distribution over all proteins.
unst <- tagmMcmcPredict(unst, params = mcmc_unst_pooled, probJoint = TRUE)
lps <- tagmMcmcPredict(lps, params = mcmc_lps_pooled, probJoint = TRUE)The TAGM results are appended to the fData slot of the datasets. As the above chunk is not run dynamically here we can load the results from the pRolocdata package (and they can also be found in Supplementary Table 6 of2). We load the datasets called thpLOPIT_unstimulated_mulvey2021 and thpLOPIT_lps_mulvey2021 which contain all machine learning results (as per the above) from.2 As per the above the analysis this was conducted on proteins common in all experiments.
The function prettyTSNE is a function specifically written to generate publication quality spatial maps. It calls the plot2D function in pRoloc and adds some customisation. We would recommend for general analysis you use the plot2D function in pRoloc which is called by typing plot2D(thpLOPIT_lps_mulvey2021) or using the pRolocGUI package.
## Load the data from pRolocdata
data("thpLOPIT_unstimulated_mulvey2021")
data("thpLOPIT_lps_mulvey2021")
## We subset for proteins common in all experiments
cmn <- commonFeatureNames(thpLOPIT_unstimulated_mulvey2021,
thpLOPIT_lps_mulvey2021)
unst <- cmn[[1]]
lps <- cmn[[2]]
## Generate the t-SNE coords
set.seed(399)
tsne_unst <- plot2D(unst, method = "t-SNE", plot = FALSE)
set.seed(399)
tsne_lps <- plot2D(lps, method = "t-SNE", plot = FALSE)
## plot TAGM assignments
par(mfrow = c(2, 2))
mycol <- paste0(getStockcol())
oo <- c(1:3, 10, 5, 4, 6:7, 9, 8, 11)
myleg <- c(getMarkerClasses(unst), "Unknown")
prettyTSNE(tsne_unst, unst, fcol = "tagm.mcmc.allocation",
main = "TAGM-MCMC allocation\nunstimulated THP1-cells",
orgOrder = oo, mainCol = mycol, outlineCol = darken(mycol))
prettyTSNE(tsne_lps, lps, fcol = "tagm.mcmc.allocation",
main = "TAGM-MCMC allocation\n12h-LPS stimulated THP1-cells",
orgOrder = oo, mainCol = mycol, outlineCol = darken(mycol))
plot(NULL, xaxt='n',yaxt='n',bty='n',ylab='',xlab='', xlim=0:1, ylim=0:1)
legend("topleft", legend = myleg, col = mycol, bty = "n",
pch = 19, cex = 1.2, pt.cex = 1.6, ncol = 2)Figure 4.5: t-SNE plots of the TAGM output on the (concatenated) LOPIT datasets for each condition
The results from the TAGM-MCMC method are appended to the fData of the MSnSet e.g. see fData(thpLOPIT_unstimulated_mulvey2021)$tagm.mcmc.allocation and fvarLabels(thpLOPIT_unstimulated_mulvey2021) to see all available slots.
Relevent to this analysis we examine the following output slots
- tagm.mcmc.allocation: the TAGM-MCMC predictions for the most probable protein sub-cellular allocation.
- tagm.mcmc.probability: the mean posterior probability for the protein sub-cellular allocations
- tagm.mcmc.outlier: the posterior probability for the protein to belong to the outlier component.
- tagm.mcmc.probability.lowerquantile and tagm.mcmc.probability.upperquantile are the lower and upper boundaries to the equi-tailed 95% credible interval of tagm.mcmc.probability.
4.5.3 Thresholding
As with all supervised learning algorithms the classifier is only able to predict a location to one of the classes that are found in the training set. Our training set contained 11 subcellular niches, as described above. It is common practice in supervised machine learning to set a specific score cutoff/threshold on which to define new assignments/allocations, below which classifications are left unassigned/unknown if we do not expect all examples (proteins) to fall into one of the categories in the discrete training set. Indeed, we do not expect the whole subcellular diversity to be represented by the 11 niches used here, we expect there to be many more, many of which will be multiply localised within the cell. It is important to allow for the possibility of proteins to fall reside in multiple locations (see15 for more details).
One advantage of using a Bayesian framework is the outputs of the classifier are probabilities. This not only allows us to look at the distribution of probabilities over all subcellular classes but also allows us to extract a probability score threshold from the product of the posterior and outlier probabilities, on which we can define new assignments, we call this our localisation probability.
localisation probability = posterior probability * outlier probability
The localisation probability is calculated for all proteins in each dataset and appended to the fData slot of each dataset.
fData(unst)$localisation.prob <- fData(unst)$tagm.mcmc.probability * (1 - fData(unst)$tagm.mcmc.outlier)
fData(lps)$localisation.prob <- fData(lps)$tagm.mcmc.probability * (1 - fData(lps)$tagm.mcmc.outlier)As described in the methods of [1] and as demonstrated in the code chunk below, we take a conservative approach, only assign proteins to a subcellular niche if the posterior probability was greater than 0.99 and if the outlier probability was very small < 1e-6, else proteins were left unassigned and labelled as proteins of “unknown location” in the data.
Our assignment threshold which we apply to the localisation probability is therefore 0.99 * 1e-6 = 0.99. We use the getPredictions function on the calculated localisation.prob to extract these newly assigned proteins.
## Threshold = (posterior > 0.99) * 1 - (outlier < 1e-6)
t_loc <- 0.99 * (1 - 1e-6)
unst <- getPredictions(unst,
fcol = "tagm.mcmc.allocation",
scol = "localisation.prob",
t = t_loc)## ans
## 40S/60S Ribosome Chromatin Cytosol
## 83 153 574
## Endoplasmic Reticulum Golgi Apparatus Lysosome
## 352 47 261
## Mitochondria Nucleolus Nucleus
## 477 39 315
## Peroxisome Plasma Membrane unknown
## 34 165 788
## ans
## 40S/60S Ribosome Chromatin Cytosol
## 91 103 440
## Endoplasmic Reticulum Golgi Apparatus Lysosome
## 387 43 266
## Mitochondria Nucleolus Nucleus
## 475 39 385
## Peroxisome Plasma Membrane unknown
## 40 227 792
We can visualise these assignments on a t-SNE plot and also plot the quantitation profiles for each subcellular class.
## plot TAGM assignments
par(mfrow = c(2, 2))
mycol <- paste0(getStockcol())
oo = c(1:3, 10, 5, 4, 6:7, 9, 8, 11)
myleg <- c(getMarkerClasses(unst), "Unknown")
prettyTSNE(tsne_unst, unst, fcol = "tagm.mcmc.allocation.pred",
main = "TAGM-MCMC final assignment\nunstimulated THP1-cells",
orgOrder = oo, mainCol = mycol, outlineCol = darken(mycol))
prettyTSNE(tsne_lps, lps, fcol = "tagm.mcmc.allocation.pred",
main = "TAGM-MCMC final assignment\n12h-LPS stimulated THP1-cells",
orgOrder = oo, mainCol = mycol, outlineCol = darken(mycol))
plot(NULL, xaxt='n',yaxt='n',bty='n',ylab='',xlab='', xlim=0:1, ylim=0:1)
legend("topleft", legend = myleg, col = mycol, bty = "n",
pch = 19, cex = 1.2, pt.cex = 1.6, ncol = 2)Figure 4.6: t-SNE plots showing the final subcellular assignments of the (concatenated) LOPIT datasets for each condition (Figure 4 of Mulvey et al 2021)
Not including the 783 marker proteins, after classification and thresholding we find 1717 and 1713 proteins to localise to one of the 11 subcellular niches in the data for the unstimulated and 12h-LPS stimulated datasets respectively.
We can examine the individual protein profiles for each protein class by using the plotDist function from pRoloc.
## Unstimulated protein profiles
par(mfrow = c(4, 3))
cl <- getMarkerClasses(unst)
data <- unst[, order(pData(unst)[["Replicate"]])]
for (i in seq(cl)) {
par(mar = c(8, 4, 9, 2), las = 2)
plotDist(data[fData(data)$markers == getMarkerClasses(data)[i], ],
pcol = paste0(getStockcol()[i], 90), xlab = "", ylim = c(0, .9))
title(main = cl[i])
}(#fig:plotdist_run)Protein quantitation profiles for proteins in the unstimulated experiments grouped by subcellular localisation
## LPS protein profiles
par(mfrow = c(4, 3))
cl <- getMarkerClasses(lps)
data <- unst[, order(pData(unst)[["Replicate"]])]
for (i in seq(cl)) {
par(mar = c(8, 4, 8, 2), las = 2)
plotDist(data[ fData(data)$markers == getMarkerClasses(data)[i], ],
pcol = paste0(getStockcol()[i], 90), xlab = "", ylim = c(0, .9))
title(main = cl[i])
}(#fig:plotdist2_run)FProtein quantitation profiles for proteins in the 12h-LPS stimulated experiments grouped by subcellular localisation and ordered along the x-axis by replciate and fraction
4.5.4 Overlap in protein locations
The code chunk below shows a summary of of the protein residency in each condition for the 3288 proteins common in all experiments.
## organelleMarkers
## 40S/60S Ribosome Chromatin Cytosol
## 75 73 52
## Endoplasmic Reticulum Golgi Apparatus Lysosome
## 69 39 49
## Mitochondria Nucleolus Nucleus
## 197 38 91
## Peroxisome Plasma Membrane unknown
## 29 71 2505
## organelleMarkers
## 40S/60S Ribosome Chromatin Cytosol
## 75 73 52
## Endoplasmic Reticulum Golgi Apparatus Lysosome
## 69 39 49
## Mitochondria Nucleolus Nucleus
## 197 38 91
## Peroxisome Plasma Membrane unknown
## 29 71 2505
kable(rbind("Unstimulated" = table(loc_unst), "LPS" = table(loc_lps)),
caption = "Protein residency in each condition of markers proteins")| 40S/60S Ribosome | Chromatin | Cytosol | Endoplasmic Reticulum | Golgi Apparatus | Lysosome | Mitochondria | Nucleolus | Nucleus | Peroxisome | Plasma Membrane | unknown | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Unstimulated | 75 | 73 | 52 | 69 | 39 | 49 | 197 | 38 | 91 | 29 | 71 | 2505 |
| LPS | 75 | 73 | 52 | 69 | 39 | 49 | 197 | 38 | 91 | 29 | 71 | 2505 |
## organelleMarkers
## 40S/60S Ribosome Chromatin Cytosol
## 83 153 574
## Endoplasmic Reticulum Golgi Apparatus Lysosome
## 352 47 261
## Mitochondria Nucleolus Nucleus
## 477 39 315
## Peroxisome Plasma Membrane unknown
## 34 165 788
## organelleMarkers
## 40S/60S Ribosome Chromatin Cytosol
## 91 103 440
## Endoplasmic Reticulum Golgi Apparatus Lysosome
## 387 43 266
## Mitochondria Nucleolus Nucleus
## 475 39 385
## Peroxisome Plasma Membrane unknown
## 40 227 792
kable(rbind("Unstimulated" = table(loc_unst), "LPS" = table(loc_lps)),
caption = "Protein residency in each condition following TAGM classification")| 40S/60S Ribosome | Chromatin | Cytosol | Endoplasmic Reticulum | Golgi Apparatus | Lysosome | Mitochondria | Nucleolus | Nucleus | Peroxisome | Plasma Membrane | unknown | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Unstimulated | 83 | 153 | 574 | 352 | 47 | 261 | 477 | 39 | 315 | 34 | 165 | 788 |
| LPS | 91 | 103 | 440 | 387 | 43 | 266 | 475 | 39 | 385 | 40 | 227 | 792 |
The heatmap below shows the sub-cellular distribution of proteins between the two conditions including the 783 annotated marker proteins (Figure 4A, Supplementary Table 7 of2). Using TAGM a additional 1,717 proteins in the unstimulated dataset and 1,713 proteins in the LPS dataset were classified to distinct subcellular regions with high confidence. The remaining proteins that did not meet the classifier threshold were left unassigned and labelled as “unknown”. As already mentioned above we do not expect all proteins to localise to one main discrete location, many proteins are known to “moonlight”18 and live in mixed locations. There was however a high degree of correlation between unstimulated and stimulated datasets, with 61% of the identified proteome sharing the same organelle localisation in both conditions (75% including the marker proteins).
source("R/intersection.R")
## Add a label to the LPS dataset so when we combine it
## with the unstimulated the information is not lost
.lps <- lps
.lps <- updateFvarLabels(.lps, "LPS")
cmb <- MSnbase::combine(unst, .lps) # now combine all results
df_all <- compareDatasets(cmb,
fcol1 = "localisation.pred",
fcol2 = "localisation.pred.LPS")
ggheatmap(df_all, title = "TAGM locations between conditions")Figure 4.7: Heatmap showing the distribution and overlap in organelle assignments between the TAGM classifications in the unstimulated data and classifications in the LPS-stimulated data
4.6 Translocations
One of the main aims of the THP-1 study in2 was to use the hyperLOPIT technology to investigate the (spatial) changes in protein localisation between the unstimulated and 12h-LPS stimulated conditions. In this section we look at how the assigned location of proteins differ between the two conditions. We examine their assigned location from TAGM and also the difference between their joint posterior probability distributions.
Re-localisations i.e. proteins that do not localise to the same subcellular niche in both conditions, were extracted and categorised as one of four different translocation events based on their class labels:
- Type 1: organelle-to-organelle - cases where proteins are assigned to different subcellular classes in each condition i.e. those that move from one discrete location to another.
- Type 2: unknown-to-organelle - cases where proteins in the unstimulated data are labelled as “unknown” but are localised to one of the 11 organelle classes in the 12h-LPS stimulated data.
- Type 3: organelle-to-unknown - cases where proteins are assigned a location to one of the 11 organelle classes in the unstimulated data but in the 12h-LPS data are labelled as “unknown”.
- Type 4: dynamic proteins that were not assigned a subcellular niche but did have a large difference in their joint probability distribution (as calculated by the natural L2 distance, also known as the Euclidean norm).
The L2 distance is denoted by \[ d_{_{L2}norm}(x, y) = \sqrt {\sum_{i = 1}^{n}{(x_i - y_i)^2}} \] where x and y are the posterior probabilities for for the unstimulated and 12h-LPS stimulated respectively, for each ith class.
As already mentioned, proteins labelled as “unknown” or “unlabelled”, describe proteins that did not meet the classifier threshold to be assigned to one of the 11 discrete organelle categories, as defined in our marker set. We not only wish to examine proteins that move between discrete locations (which we call type 1 translocations above) but we also wish to examine cases where in one condition the protein has been given a discrete location, and in another condition it has been described as “unknown”, and therefore we can confidently say it does not belong to one of the 11 subcellular classes. It is important to note that in terms of machine learning, the term “unknown” is not a class in the training set, it is simply as term we use in our pipeline to describe proteins that we can say can not confidently be assigned to one of the 11 classes.
These cases are still of great interest as although we can not pinpoint exactly where the protein resides in this snapshot of time we do know it is not classed to the same location in the other condition. Unknown cases encompass a number of scenarios for example, a protein having a mixed population and moonlighting between organelles, or it be that the protein localised to a subcellular niche that does not appear in our training data. Whichever reason, what we are interested in is not only a change in location, but the size of the probability change, as this implies a change in localisation regardless of organelle residency.
As an extra measure of stringency we enforce that all “unknown” proteins which are considered as translocations must have a very high outlier probability (as per the below code chunk out = 1e-3) so we can say they are confidently not a member of any of the 11 classes.
For every protein the natural L2 distance (Euclidean norm) was calculated between the TAGM joint posterior probability distributions to provide and extra source of information on which to rank proteins of interest. The L2 distance was used for defining potential type 4 translocations where proteins did not meet the criteria to be assigned to one of the organelle classes in the training data but did exhibit large changes in their probability distribution as deduced by the L2 value. Only proteins with the maximum L2 distance of 1 were extracted as type 4 candidates for further data mining. This small subset comprised of 30 proteins (see below).
In the below code chunk we call the function getTranslocations which extracts the localisations of every protein in each condition then assigns a translocation type as described above and then calculates the L2 distance between the posterior probability distributions. This information is appended to the fData slot of our MSnSet along with all the other machine learning results.
# Source getMovers code for extracting translocations
# https://github.com/CambridgeCentreForProteomics/thp-lopit-2021/blob/main/R/getmovers.R
source("R/getmovers.R")
extract_movers <- getTranslocations(unst, lps,
fcol = "tagm.mcmc.allocation.pred",
out = 1e-3)
unst <- extract_movers[[1]]
lps <- extract_movers[[2]]
getMarkers(unst, "translocations")## organelleMarkers
## type1 type2 type3 type4
## 112 62 49 30
We find we have - - 112 type 1 - 62 type 2 - 49 type 3 - 30 type 4 proteins that move following 12 hour stimulation with LPS.
In the next section we can further examine and plot these events using alluvial and circos plots and map them onto our t-SNE spatial maps in each condition.
4.6.1 Visualisation of translocations
The following code chunks use functions from the circlize and ggalluvial packages (full source code can be found in the R directory of this repo) to generate circos and alluvial plots respectively. These plots summarise the flow of proteins between organelle locations and the two conditions.
4.6.1.1 Circos plot of protein translocations across organelles
# Source code for circos plots
# https://github.com/CambridgeCentreForProteomics/thp-lopit-2021/blob/main/R/circos.R
source("R/circos.R")
## generate my colour scheme
circos_cols <- c(getStockcol(), "grey")
orgs <- c(union(getMarkerClasses(unst), getMarkerClasses(lps)), "unknown")
(colscheme <- setNames(circos_cols, orgs)) # check levels consistent ## 40S/60S Ribosome Chromatin Cytosol
## "#88CCEE" "#332288" "#53CAB7"
## Endoplasmic Reticulum Golgi Apparatus Lysosome
## "#0170b4" "#204f20" "#990000"
## Mitochondria Nucleolus Nucleus
## "#E69F00" "#DDCC77" "#E18493"
## Peroxisome Plasma Membrane unknown
## "#AA4499" "#D55E00" "grey"
## get indices of translocating proteins
tl <- !is.na(fData(unst)$translocations)
## set circos plot parameters
par(mar = c(2, 2, 2, 2), cex = .5)
circos.clear()
circos.par(gap.degree = 4)
## plot circos
customChord(unst[tl, ], lps[tl, ],
cols = colscheme,
diffHeight = -0.02,
transparency = 0.3,
link.sort = FALSE,
labels = TRUE)Note: labels were optimised in Inkscape
Figure 4.8: Directional circos plot showing protein translocations (Fig. S4A of Mulvey et al 2021
4.6.1.2 Alluvial (river) plot of protein translocations across organelles
# Source code for producing river plots. Not labels optimsied in Inkscape
# https://github.com/CambridgeCentreForProteomics/thp-lopit-2021/blob/main/R/riverplot.R
source("r/riverplot.R")
library(ggalluvial)
thp_alluvial <- riverplot(unst[tl, ], lps[tl, ],
cols = colscheme,
labels = TRUE)
thp_alluvial + ggtitle("Translocations following 12h-LPS stimulation in THP-1 cells") Figure 4.9: Alluvial (river) plot showing the 253 protein translocations (Fig. 4C of Mulvey et al. 2021)
Note: labels were optimised in Inkscape
Alluvial (river) plot showing the 253 protein translocations (Figure 4C of2) proteins which were found to move between organelles at 12h-LPS. The number of proteins that are found to translocate to and from each subcellular compartment is denoted next to the labelled alluvial blocks
4.6.2 Spatial map of translocating proteins
The t-SNE maps below also show the spatial localisation of translocating proteins. We see that translocation events appear across a number of organelles.
source("r/foi.R")
par(mfrow = c(1, 2))
## Unstimulated
prettyTSNE_overlay(tsne_unst, unst,
fcol = "localisation.pred",
main = "Type 1, 2, 3, or 4 translocation events", orgOrder = oo,
mainCol = paste0(lighten(mycol), 30),
outlineCol = paste0(lighten(mycol), 30))
highlightOnPlot(object = tsne_unst, pch = 21, cex = 1.7,
col = mycol[2], bg = lighten(lighten("grey")),
foi = type1, lwd = 2,
args = list(unst))
highlightOnPlot(object = tsne_unst, pch = 24, cex = 1.7,
col = darken(mycol[7]), bg = lighten(lighten("#f4f4c8")),
foi = type2, lwd = 2,
args = list(unst))
highlightOnPlot(object = tsne_unst, pch = 21, cex = 1.7,
col = darken("purple"), bg = lighten(lighten("#f2a6e3")),
foi = type3, lwd = 2,
args = list(unst))
highlightOnPlot(object = tsne_unst, pch = 24, cex = 1.7,
col = "#1c1c78", bg = lighten(lighten("#5fa8cc")),
foi = type4, lwd = 2,
args = list(unst))
prettyTSNE_overlay(tsne_lps, lps, fcol = "localisation.pred",
main = "", orgOrder = oo,
mainCol = paste0(lighten(mycol), 30),
outlineCol = paste0(lighten(mycol), 30))
## 12h-LPS
highlightOnPlot(object = tsne_lps, pch = 21, cex = 1.7,
col = mycol[2], bg = lighten(lighten("grey")),
foi = type1, lwd = 2,
args = list(lps))
highlightOnPlot(object = tsne_lps, pch = 24, cex = 1.7,
col = darken(mycol[7]), bg = lighten(lighten("#f4f4c8")),
foi = type2, lwd = 2,
args = list(lps))
highlightOnPlot(object = tsne_lps, pch = 21, cex = 1.7,
col = darken("purple"), bg = lighten(lighten("#f2a6e3")),
foi = type3, lwd = 2,
args = list(lps))
highlightOnPlot(object = tsne_lps, pch = 24, cex = 1.7,
col = "#1c1c78", bg = lighten(lighten("#5fa8cc")),
foi = type4, lwd = 2,
args = list(lps))plot(NULL, xaxt='n',yaxt='n',bty='n',ylab='',xlab='', xlim=0:1, ylim=0:1)
legend("topleft", legend = c("Type 1: organelle-to-organelle",
"Type 2: unknown-to-organelle",
"Type 3: organelle-to-unknown",
"Type 4: unknown-to-unknown"),
col = c(mycol[2], darken(mycol[7]), darken("purple"), "#1c1c78"),
pt.bg = c(lighten(lighten("grey")), lighten(lighten("#f4f4c8")),
lighten(lighten("#f2a6e3")), lighten(lighten("#5fa8cc"))),
bty = "n",
pch = c(21, 24, 21, 24), pt.cex = 2.2, cex = 1.4)Figure 4.10: T-SNE dimensionality reduction showing the 253 relocalising proteins from the hyperLOPIT experiments and plotted by Type 1,2,3, or 4 relocalisaton events, which are represented by grey circles, yellow triangles, pink circles and blue triangles, respectively.
4.6.3 Summary table of translocations between conditions
df <- makedf(unst[tl, ], lps[tl, ],
fcol1 = "localisation.pred",
fcol2 = "localisation.pred",
mrkCol1 = "markers",
mrkCol2 = "markers")## `summarise()` has grouped output by 'x'. You can override using the `.groups` argument.
names(df) <- c("Unstimulated", "LPS", "Number of translocations")
df <- df[!df$`Number of translocations`==0, ]
kable(df, caption = "Translocations between subcellular niches following 12h-LPS stimulation")| Unstimulated | LPS | Number of translocations | |
|---|---|---|---|
| 8 | 40S/60S Ribosome | Nucleus | 1 |
| 11 | 40S/60S Ribosome | unknown | 1 |
| 13 | Chromatin | Cytosol | 1 |
| 19 | Chromatin | Nucleus | 8 |
| 22 | Chromatin | unknown | 10 |
| 30 | Cytosol | Nucleus | 35 |
| 32 | Cytosol | Plasma Membrane | 8 |
| 33 | Cytosol | unknown | 19 |
| 38 | Endoplasmic Reticulum | Lysosome | 3 |
| 44 | Endoplasmic Reticulum | unknown | 3 |
| 48 | Golgi Apparatus | Endoplasmic Reticulum | 6 |
| 59 | Lysosome | Endoplasmic Reticulum | 8 |
| 60 | Lysosome | Golgi Apparatus | 2 |
| 65 | Lysosome | Plasma Membrane | 15 |
| 66 | Lysosome | unknown | 4 |
| 75 | Mitochondria | Peroxisome | 5 |
| 77 | Mitochondria | unknown | 6 |
| 85 | Nucleolus | Nucleus | 1 |
| 89 | Nucleus | 40S/60S Ribosome | 2 |
| 91 | Nucleus | Cytosol | 1 |
| 99 | Nucleus | unknown | 4 |
| 106 | Peroxisome | Mitochondria | 3 |
| 116 | Plasma Membrane | Lysosome | 13 |
| 121 | Plasma Membrane | unknown | 2 |
| 124 | unknown | Cytosol | 3 |
| 125 | unknown | Endoplasmic Reticulum | 10 |
| 126 | unknown | Golgi Apparatus | 1 |
| 127 | unknown | Lysosome | 4 |
| 128 | unknown | Mitochondria | 5 |
| 130 | unknown | Nucleus | 5 |
| 131 | unknown | Peroxisome | 2 |
| 132 | unknown | Plasma Membrane | 32 |
4.7 A scaffold for proteins of interest
Mulvey et al (2021) show that hyperLOPIT provides a means to robustly classify unannotated proteins to distinct organelles and to investigate protein relocalisation events. Supplementary figures 2 - 5 demonstrate how these spatial maps can be used as a scaffold to overlay proteins of interest including:
5 Figures from the manuscipt
5.1 Main Figures
5.1.1 Figure 1
Figure 1 was not produced in R. The schematic workflow was generated in Inkscape.
5.1.2 Figure 2
Figure 2 shows the time course of quantitative abundance changes in proteins during 24 h of LPS stimulation The volcano plots show the abundance of all 4,292 time-course proteins at 2 h, 4 h, 6 h, 12 h and 24 h of LPS stimulation.
source("r/ggVolcano.R")
## https://github.com/CambridgeCentreForProteomics/thp-lopit-2021/blob/main/R/ggVolcano.R
library("ggplot2")
library("ggrepel")
library("gridExtra")
t_2 <- read.csv("csv/limma_t2.csv", row.names = 1)
t_4 <- read.csv("csv/limma_t4.csv", row.names = 1)
t_6 <- read.csv("csv/limma_t6.csv", row.names = 1)
t_12 <- read.csv("csv/limma_t12.csv", row.names = 1)
t_24 <- read.csv("csv/limma_t24.csv", row.names = 1)
p_2 <- ggVolcano(t_2, "2 hours", N = 20, lfc = 0.6,
p = 0.05, addLegend = FALSE,
text.size = 12, base.text.size = 12,
legend.text.size = 12, geom.point.size = 2,
label.text.size = 4)
p_4 <- ggVolcano(t_4, "4 hours", N = 20, lfc = 0.6,
p = 0.01, addLegend = FALSE,
text.size = 12, base.text.size = 12,
legend.text.size = 12, geom.point.size = 2,
label.text.size = 4)
p_6 <- ggVolcano(t_6, "6 hours", N = 20, lfc = 0.6,
p = 0.01, addLegend = FALSE,
text.size = 12, base.text.size = 12,
legend.text.size = 12, geom.point.size = 2,
label.text.size = 4)
p_12 <- ggVolcano(t_12, "12 hours", N = 20, lfc = 0.6,
p = 0.01, addLegend = FALSE,
text.size = 12, base.text.size = 12,
legend.text.size = 12, geom.point.size = 2,
label.text.size = 4)
p_24 <- ggVolcano(t_24, "24 hours", N = 20, lfc = 0.6,
p = 0.01, addLegend = FALSE,
text.size = 12, base.text.size = 12,
legend.text.size = 12, geom.point.size = 2,
label.text.size = 4)
# grid.arrange(p_2 p_4, p_6, p_12, p_24, nrow = 3, ncol = 2)
p_2 + ggtitle("Volcano at 2h-LPS")
p_4 + ggtitle("Volcano at 4h-LPS")
p_6 + ggtitle("Volcano at 6h-LPS")
p_12 + ggtitle("Volcano at 12h-LPS")
p_24 + ggtitle("Volcano at 24h-LPS")Quantitative values for intracellular proteomics abundance (red) as well as extracellular, cytokine secretion levels as measured by ELISA (blue) for IL1B and CXCL10 expression.
source("r/plotLineGraph.R")
# https://github.com/CambridgeCentreForProteomics/thp-lopit-2021/blob/main/R/plotLineGraph.R
library("pRoloc")
library("pRolocdata")
library("ggplot2")
library("tidyr")
library("Rmisc")
library("gridExtra")
## read in elisa data
elisa_il1b_wide <- read.csv("csv/elisa_il1b.csv")
elise_cxcl_wide <- read.csv("csv/elisa_cscl10.csv")
## convert to long tidy format for ggplot
elisa_il1b_long <- gather(elisa_il1b_wide, replicate, measurement, X1:X6, factor_key = TRUE)
elisa_cxcl10_long <- gather(elise_cxcl_wide, replicate, measurement, X1:X6, factor_key = TRUE)
p <-
plotLineGraph(elisa_il1b_wide, "median",
linecol = "#1B83E9", themeSize = 14) +
ggtitle("Elisa data: IL-1B") +
theme(plot.title = element_text(hjust = 0.5))
q <- plotLineGraph(elise_cxcl_wide, "median",
linecol = "#1B83E9", themeSize = 14) +
ggtitle("Elisa data: CXCL10") +
theme(plot.title = element_text(hjust = 0.5))
## get quantitation data
IL1B <- "P01584"
CXCL10 <- "P02778"
## Load protein data
data("lpsTimecourse_rep1_mulvey2021")
data("lpsTimecourse_rep2_mulvey2021")
data("lpsTimecourse_rep3_mulvey2021")
x1 <- lpsTimecourse_rep1_mulvey2021
x2 <- lpsTimecourse_rep2_mulvey2021
x3 <- lpsTimecourse_rep3_mulvey2021
## convert to long tidy format for ggplot
lopit_il1b_wide <- t(rbind(exprs(x1[IL1B,]), exprs(x2[IL1B,]),exprs(x3[IL1B,])))
lopit_cxcl10_wide <- t(rbind(exprs(x1[CXCL10,]), exprs(x2[CXCL10,]),exprs(x3[CXCL10,])))
lopit_il1b_wide <- data.frame(cbind(Time = c(0, 2, 4, 6, 12, 24), lopit_il1b_wide))
lopit_cxcl10_wide <- data.frame(cbind(Time = c(0, 2, 4, 6, 12, 24), lopit_cxcl10_wide))
colnames(lopit_cxcl10_wide) <- colnames(lopit_il1b_wide) <- c("Time", "X1", "X2", "X6")
lopit_il1b_long <- gather(lopit_il1b_wide, replicate, measurement, X1:X6, factor_key = TRUE)
lopit_cxcl10_long <- gather(lopit_cxcl10_wide, replicate, measurement, X1:X6, factor_key = TRUE)
## plot quantitation profiles
r = plotLineGraph(lopit_il1b_wide,
linecol = "#C50000",
.ylab = "Abundance\n",
themeSize = 14) +
ylim(c(1.5, 7)) +
ggtitle("Shotgun: IL-1B") +
theme(plot.title = element_text(hjust = 0.5))
s = plotLineGraph(lopit_cxcl10_wide,
linecol = "#C50000",
.ylab = "Abundance\n",
themeSize = 14) +
ylim(c(1.5, 7)) +
ggtitle("Shotgun: CXCL10") +
theme(plot.title = element_text(hjust = 0.5))
grid.arrange(p, q, r, s, ncol = 2, nrow = 2)Heatmap of the protein abundance for the 72 proteins significantly changed in abundance by 12h-LPS during the time course analysis.
library("gplots")
library("plotrix")
library("scico")
## restructure the gather the data for heatmap
dat <- read.csv("csv/timecourse_t12.tsv", row.names = 1, sep = "\t")
rownames(dat) <- NULL
dat <- dat %>%
filter(Significance != "Not significant") %>%
tibble::column_to_rownames("GN") %>%
select(1:18) %>% as.matrix()
calcMeds <- function(df, .grepName) {
ind <- grep(.grepName, colnames(df))
.df <- df[, ind]
.mean <- rowMedians(.df)
return(.mean)
}
t0 <- calcMeds(dat, "X0.hr")
t2 <- calcMeds(dat, "X2.hr")
t4 <- calcMeds(dat, "X4.hr")
t6 <- calcMeds(dat, "X6.hr")
t12 <- calcMeds(dat, "X12.hr")
t24 <- calcMeds(dat, "X24.hr")
dat_meds <- cbind(t0, t2, t4, t6, t12, t24)
rownames(dat_meds) <- rownames(dat)
colnames(dat_meds) <- c(0, 2, 4, 6, 12, 24)
## set colour palette - use the scico package
my_palette <- scico(72, palette = "berlin")
## Plot heatmap
heatmap.2(dat_meds, density.info = "none", trace = "none",
col = my_palette, Colv = NA, dendrogram = "row",
key=TRUE, cexCol = 2, cexRow = 1.3, margin = c(6,8),
lhei=c(.8,3.5), lwid=c(0.2,0.8), offsetRow=0.3)5.1.3 Figure 3
Bayesian temporal clustering of the LPS time series demonstrates clusters of co-regulated proteins and GO analysis.
library("RColorBrewer")
source("r/plotRibbons.R")
# https://github.com/CambridgeCentreForProteomics/thp-lopit-2021/blob/main/R/plotRibbons.R
## Read in MDI clustering results
mdi_rep1 <- read.csv("csv/mdi_clustering_lpsrep1.csv")
mdi_rep2 <- read.csv("csv/mdi_clustering_lpsrep2.csv")
mdi_rep3 <- read.csv("csv/mdi_clustering_lpsrep3.csv")
mdi <- read.csv("csv/mdi_clusters_output.csv")
# get median normalised intensity
dat_mat <- list(data.matrix(mdi_rep1[, -1]),
data.matrix(mdi_rep2[, -1]),
data.matrix(mdi_rep3[, -1]))
av_mat <- apply(simplify2array(dat_mat), c(1,2), median)
rownames(av_mat) <- mdi_rep1[,1]
colnames(av_mat) <- c(0, 2, 4, 6, 12, 24)
## plot clusters of interest
ids <- c(1:6, 9:11, 13, 14, 17)
mdi_profs <- sapply(ids, function(z)
av_mat[mdi$Protein.Accession[which(mdi$Cluster.Number == z)], ])
names(mdi_profs) <- paste0("cluster", ids)
## pick a good palette
ribbonCol <- c(brewer.pal(n = 9, "Oranges")[-c(1:3)],
brewer.pal(n = 9, "GnBu")[-c(1:3)])
par(mfrow = c(3,2), mar = c(6, 5, 3, 3))
for (i in 1:6) {
ribbonPlot(mdi_profs[[i]], col = ribbonCol[i], c(0.05, .95),
main = paste("Cluster", ids[i]), cex.main = 2, size = 2)
}par(mfrow = c(3,2), mar = c(6, 5, 3, 3))
for (i in 7:12) {
ribbonPlot(mdi_profs[[i]], col = ribbonCol[i], c(0.05, .95),
main = paste("Cluster", ids[i]), cex.main = 2, size = 2)
}source("r/GObarplot.R")
# https://github.com/CambridgeCentreForProteomics/thp-lopit-2021/blob/main/R/GObarplot.R
GObarplots(filename = "csv/david_data_gobp.csv", cols = ribbonCol, N = 30) +
ggtitle("GO Biological Process Terms")GObarplots(filename = "csv/david_data_gocc.csv", cols = ribbonCol) +
ggtitle("GO Cellular Component Terms")GObarplots(filename = "csv/david_data_gomf.csv", cols = ribbonCol, N = 15) +
ggtitle("GO Molecular Function Terms")Figure 5.1: Gene Ontology Biological Process (GOBP) (C), Cellular Component (GOCC) (D) and Molecular Function (GOMF) (E) annotation term enrichment for the clusters are shown. X-axis: –log10(adj.p-value). The numbers within the barcharts refer to the number of proteins associated with that term in each cluster.
5.1.4 Figure 4
Assignment of proteins to subcellular organelles using TAGM-MCMC semi-supervised classifier for spatial proteomics data.
source("r/prettymap.R")
# https://github.com/CambridgeCentreForProteomics/thp-lopit-2021/blob/main/R/prettymap.R
library("pRoloc")
library("pRolocdata")
## set organelle colours
mycol <- c("#88CCEE", "#332288", "#53CAB7", "#0170b4", "#204f20", "#990000",
"#E69F00", "#DDCC77", "#E18493", "#AA4499", "#D55E00", "grey")
setStockcol(mycol)
setUnknownpch(16)
## get data
data("thpLOPIT_unstimulated_mulvey2021")
data("thpLOPIT_lps_mulvey2021")
data <- commonFeatureNames(thpLOPIT_unstimulated_mulvey2021, thpLOPIT_lps_mulvey2021)
unst <- data[[1]]
lps <- data[[2]]
## Generate the t-SNE coords (Figure 4 of [1])
set.seed(399)
tsne_unst <- plot2D(unst, method = "t-SNE", plot = FALSE)
set.seed(399)
tsne_lps <- plot2D(lps, method = "t-SNE", plot = FALSE)
## plot the data as t-SNE maps
par(mfrow = c(3, 2))
oo = c(1:3, 10, 5, 4, 6:7, 9, 8, 11) # specify plot order
## Plot marker proteins
prettyTSNE(tsne_unst, unst, fcol = "markers",
main = "Subcellular markers\nunstimulated THP1-cells",
orgOrder = oo, mainCol = mycol, outlineCol = darken(mycol))
prettyTSNE(tsne_lps, lps, fcol = "markers",
main = "Subcellular markers\n12h-LPS stimulated THP1-cells",
orgOrder = oo, mainCol = mycol, outlineCol = darken(mycol))
## Plot results from classification by TAGM-MCMC
prettyTSNE(tsne_unst, unst, fcol = "localisation.pred",
main = "Classification by TAGM-MCMC\nunstimulated THP1-cells",
orgOrder = oo, mainCol = mycol, outlineCol = darken(mycol))
prettyTSNE(tsne_lps, lps, fcol = "localisation.pred",
main = "Classification by TAGM-MCMC\n12h-LPS stimulated THP1-cells",
orgOrder = oo, mainCol = mycol, outlineCol = darken(mycol))
## add a legend
myleg <- c(getMarkerClasses(unst), "Unknown")
plot(NULL, xaxt='n',yaxt='n',bty='n',ylab='',xlab='', xlim=0:1, ylim=0:1)
legend("topleft", legend = myleg, col = mycol, bty = "n",
pch = 19, cex = 1, pt.cex = 1.6, ncol = 2)Alluvial plot of translocating proteins
source("r/riverplot.R")
# https://github.com/CambridgeCentreForProteomics/thp-lopit-2021/blob/main/R/riverplot.R
library("ggalluvial")
library("pRoloc")
library("pRolocdata")
## set organelle colours
mycol <- c("#88CCEE", "#332288", "#53CAB7", "#0170b4", "#204f20", "#990000",
"#E69F00", "#DDCC77", "#E18493", "#AA4499", "#D55E00", "grey")
setStockcol(mycol)
setUnknownpch(16)
## get data
data("thpLOPIT_unstimulated_mulvey2021")
data("thpLOPIT_lps_mulvey2021")
data <- commonFeatureNames(thpLOPIT_unstimulated_mulvey2021, thpLOPIT_lps_mulvey2021)
unst <- data[[1]]
lps <- data[[2]]
fData(unst)$translocations <- fData(lps)$translocations <- NA
fData(unst)$translocations[which(fData(unst)$type1_translocation)] <-
fData(lps)$translocations[which(fData(lps)$type1_translocation)] <- "type1"
fData(unst)$translocations[which(fData(unst)$type2_translocation)] <-
fData(lps)$translocations[which(fData(lps)$type2_translocation)] <- "type2"
fData(unst)$translocations[which(fData(unst)$type3_translocation)] <-
fData(lps)$translocations[which(fData(lps)$type3_translocation)] <- "type3"
fData(unst)$translocations[which(fData(unst)$type4_translocation)] <-
fData(lps)$translocations[which(fData(lps)$type4_translocation)] <- "type4"
## generate my colour scheme
circos_cols <- c(getStockcol(), "grey")
orgs <- c(union(getMarkerClasses(unst), getMarkerClasses(lps)), "unknown")
colscheme <- setNames(circos_cols, orgs) # check levels consistent
## get indices of translocating proteins
tl <- !is.na(fData(unst)$translocations)
thp_alluvial <- riverplot(unst[tl, ], lps[tl, ],
cols = colscheme,
labels = TRUE)
thp_alluvial + ggtitle("Translocations following 12h-LPS stimulation in THP-1 cells") 5.1.5 Figure 5
Relocalisation of RHO-GTPase trafficking molecules to the PM. Relocalisation of RHO-GTPase family members and accessory proteins were found in response to LPS, including CDC42, RAC1, RHOA, RHOC, SRGAP2, ARHGAP18, APBB1IP.
source("r/prettymap.R")
# https://github.com/CambridgeCentreForProteomics/thp-lopit-2021/blob/main/R/prettymap.R
library("pRoloc")
library("pRolocdata")
## set organelle colours
mycol <- c("#88CCEE", "#332288", "#53CAB7", "#0170b4", "#204f20", "#990000",
"#E69F00", "#DDCC77", "#E18493", "#AA4499", "#D55E00", "grey")
setStockcol(mycol)
setUnknownpch(16)
## get data
data("thpLOPIT_unstimulated_mulvey2021")
data("thpLOPIT_lps_mulvey2021")
data <- commonFeatureNames(thpLOPIT_unstimulated_mulvey2021, thpLOPIT_lps_mulvey2021)
unst <- data[[1]]
lps <- data[[2]]
## Generate the t-SNE coords (Figure 4 of [1])
set.seed(399)
tsne_unst <- plot2D(unst, method = "t-SNE", plot = FALSE)
set.seed(399)
tsne_lps <- plot2D(lps, method = "t-SNE", plot = FALSE)
## ======= highlighting interesting proteins ==========
CDC42 <- "P60953" # cytosol to PM
APBB1IP <- "Q7Z5R6" # unknown to PM
SRGAP2C <- "O75044" # unknown to PM
ARHGAP18 <- "Q8N392" # unknown to PM
RHOA <- "P61586" # unknown to PM
RAC1 <- "P63000-2" # unknown to PM
RHOC <- "P08134" # unknown to unknown
set1 <- c(APBB1IP, SRGAP2C, ARHGAP18, RHOA, RAC1, RHOC)
names(set1) <- c("APBB1IP", "SRGAP2C", "ARHGAP18", "RHOA", "RAC1", "RHOC")
## plot the spatial map with proteins highlighted
par(mfrow = c(2, 2))
# pdf("figures/figure5_unstim.pdf", width=7.5, height=8)
prettyTSNE_overlay(tsne_unst, unst, fcol = "localisation.pred",
main = "Unstimulated THP-1 cells", orgOrder = oo,
mainCol = paste0(darken(mycol), 20),
outlineCol = paste0(lighten(mycol), 20))
points(tsne_unst[RHOC, , drop = FALSE], pch = 24, col = "black", cex = 2, bg = "#D7DADE")
points(tsne_unst[set1[-6], , drop = FALSE], pch = 24, col = "black", cex = 2, bg = "#D7DADE")
points(tsne_unst[CDC42, , drop = FALSE], pch = 24, col = "black", cex = 2, bg = "red3")
text(x = 24, y = -14, labels = "RHOC", font = 2, cex = 1.2)
text(x = 7, y = -16, labels = "RHOA", font = 2, cex = 1.2)
text(x = 24, y = -11, labels = "APBB1IP", font = 2, cex = 1.2)
text(x = 22, y = -17, labels = "RAC1", font = 2, cex = 1.2)
text(x = 7, y = -13, labels = "SRGAP2C", font = 2, cex = 1.2)
text(x = 8, y = -10, labels = "ARHGAP18", font = 2, cex = 1.2)
text(x = 18, y = -7, labels = "CDC42", font = 2, col = "red3", cex = 1.2)
# dev.off()
# pdf("figures/figure5_lps.pdf", width=7.5, height=8)
prettyTSNE_overlay(tsne_lps, lps, fcol = "localisation.pred",
main = "12h-LPS stimulated THP-1 cells", orgOrder = oo,
mainCol = paste0(lighten(mycol), 20),
outlineCol = paste0(lighten(mycol), 20))
points(tsne_lps[RHOC, , drop = FALSE], pch = 24, col = "black", cex = 2, bg = "#D7DADE")
points(tsne_lps[set1[-6], , drop = FALSE], pch = 24, col = "black", cex = 2, bg = "#D7DADE")
points(tsne_lps[CDC42, , drop = FALSE], pch = 24, col = "black", cex = 2, bg = "red3")
text(x = 12, y = -11.5, labels = "RHOC", font = 2, cex = 1.2)
text(x = 30, y = -16, labels = "RHOA", font = 2, cex = 1.2)
text(x = 30, y = -8, labels = "APBB1IP", font = 2, cex = 1.2)
text(x = 14, y = -21, labels = "RAC1", font = 2, cex = 1.2)
text(x = 11, y = -16.5, labels = "SRGAP2C", font = 2, cex = 1.2)
text(x = 29, y = -10, labels = "ARHGAP18", font = 2, cex = 1.2)
text(x = 28, y = -23, labels = "CDC42", font = 2, col = "red3", cex = 1.2)
# dev.off()
## add a legend
myleg <- c(getMarkerClasses(unst), "Unknown")
plot(NULL, xaxt='n',yaxt='n',bty='n',ylab='',xlab='', xlim=0:1, ylim=0:1)
legend("topleft", legend = myleg, col = mycol, bty = "n",
pch = 19, cex = 1, pt.cex = 1.6, ncol = 2)Figure 5.2: t-SNE maps for the unstimulated (left) and 12h-LPS stimulated (right) showing relocalisation of RHO-GTPase trafficking molecules to the PM
5.1.6 Figure 6
Proteins can exhibit both spatial and temporal regulation by LPS. 15 proteins were altered in abundance during the time-course of LPS stimulation and also translocated to different subcellular regions.
source("r/prettymap.R")
# https://github.com/CambridgeCentreForProteomics/thp-lopit-2021/blob/main/R/prettymap.R
library("pRoloc")
library("pRolocdata")
## set organelle colours
mycol <- c("#88CCEE", "#332288", "#53CAB7", "#0170b4", "#204f20", "#990000",
"#E69F00", "#DDCC77", "#E18493", "#AA4499", "#D55E00", "grey")
setStockcol(mycol)
setUnknownpch(16)
## get data
data("thpLOPIT_unstimulated_mulvey2021")
data("thpLOPIT_lps_mulvey2021")
data <- commonFeatureNames(thpLOPIT_unstimulated_mulvey2021, thpLOPIT_lps_mulvey2021)
unst <- data[[1]]
lps <- data[[2]]
## Generate the t-SNE coords (Figure 4 of [1])
set.seed(399)
tsne_unst <- plot2D(unst, method = "t-SNE", plot = FALSE)
set.seed(399)
tsne_lps <- plot2D(lps, method = "t-SNE", plot = FALSE)
## ======= highlighting interesting proteins ==========
# CHCHD2P9 -> Q9Y6H1 -> 3279
# CKAP2 -> Q8WWK9-5 -> 2265
# TCEB3 -> Q14241 -> 1635
# SRP9 -> P49458 -> 1090
# MVP -> Q14764 -> 1659
# EIF4A1 -> P60842 -> 1242
# IFI35 -> P80217-2 -> 1358
# ACSL4 -> O60488 -> 223
# SPG21 -> Q9NZD8 -> 2974
# PLEK -> P08567 -> 531
# PALM -> O75781 -> 311
# DAB2 -> P98082 -> 1383
# CALCOCO2 -> Q13137-4 -> 1540
# CLEC11A -> Q9Y240 -> 3148
# SQSTM1 -> Q13501 -> 1580
## plot spatial map with points highlighted
par(mfrow = c(2, 2))
# pdf("figures/figure6_unstim.pdf", width=7.5, height=8)
## subset 15 points by label position top (t), bottom (b), left (l), right (r)
t <- c(3279, 2265, 1090, 1659, 1358, 223, 531)
b <- c(1635, 1242, 311, 2974)
l <- c(1383)
r <- c(1540)
set1 <- c(t, b, l, r)
set1 <- setdiff(set1, c(3148, 1580))
set2 <- c(3148, 1580)
prettyTSNE_overlay(tsne_unst, unst, fcol = "localisation.pred",
main = "Unstimulated THP-1 cells", orgOrder = oo,
mainCol = paste0(lighten(mycol), 10),
outlineCol = paste0(lighten(mycol), 10))
points(tsne_unst[set1, ], pch = 24, col = "black", cex = 1.4, bg = "#D7DADE")
points(tsne_unst[set2, ], pch = 24, col = "black", cex = 1.4, bg = "red3")
text(tsne_unst[b, 1], tsne_unst[b, 2], labels = fData(unst)[b, "GN"], pos = 1, font = 2)
text(tsne_unst[l, 1], tsne_unst[l, 2], labels = fData(unst)[l, "GN"], pos = 2, font = 2)
text(tsne_unst[t, 1], tsne_unst[t, 2], labels = fData(unst)[t, "GN"], pos = 3, font = 2)
text(tsne_unst[r, 1], tsne_unst[r, 2], labels = fData(unst)[r, "GN"], pos = 4, font = 2)
text(tsne_unst[3148, 1], tsne_unst[3148, 2], col = "red3", font = 2,
labels = fData(unst)[3148, "GN"], pos = 2)
text(tsne_unst[1580, 1], tsne_unst[1580, 2], col = "red3", font = 2,
labels = fData(unst)[1580, "GN"], pos = 1)
# dev.off()
# pdf("figures/figure6_lps.pdf", width=7.5, height=8)
t <- c(2265, 1242, 3279, 223)
b <- c(1090, 1659, 1358, 531, 1635, 311)
l <- c(1540, 2974)
r <- c(1383)
set1 <- c(t, b, l, r)
set1 <- setdiff(set1, c(3148, 1580))
set2 <- c(3148, 1580)
prettyTSNE_overlay(tsne_lps, lps, fcol = "localisation.pred",
main = "LPS stimulated THP-1 cells", orgOrder = oo,
mainCol = paste0(lighten(mycol), 10),
outlineCol = paste0(lighten(mycol), 10))
points(tsne_lps[set1, ], pch = 24, col = "black", cex = 1.4, bg = "#D7DADE")
points(tsne_lps[set2, ], pch = 24, col = "black", cex = 1.4, bg = "red3")
text(tsne_lps[b, 1], tsne_lps[b, 2], labels = fData(lps)[b, "GN"], pos = 1, font = 2)
text(tsne_lps[l, 1], tsne_lps[l, 2], labels = fData(lps)[l, "GN"], pos = 2, font = 2)
text(tsne_lps[t, 1], tsne_lps[t, 2], labels = fData(lps)[t, "GN"], pos = 3, font = 2)
text(tsne_lps[r, 1], tsne_lps[r, 2], labels = fData(lps)[r, "GN"], pos = 4, font = 2)
text(tsne_lps[3148, 1], tsne_lps[3148, 2], col = "red3", font = 2,
labels = fData(lps)[3148, "GN"], pos = 1)
text(tsne_lps[1580, 1], tsne_lps[1580, 2], col = "red3", font = 2,
labels = fData(lps)[1580, "GN"], pos = 3)
# dev.off()
## add a legend
myleg <- c(getMarkerClasses(unst), "Unknown")
plot(NULL, xaxt='n',yaxt='n',bty='n',ylab='',xlab='', xlim=0:1, ylim=0:1)
legend("topleft", legend = myleg, col = mycol, bty = "n",
pch = 19, cex = 1, pt.cex = 1.6, ncol = 2)Figure 5.3: t-SNE maps for the unstimulated (left) and 12h-LPS stimulated (right) showing the distribution of 15 proteins which were altered in abundance during the time-course of LPS stimulation and also translocated to different subcellular regions in hyperLOPIT space.
Protein profiles for Sequestosome (Q13501) and CLEC11A (Q9Y240) proteins
source("r/plotLineGraph.R")
# https://github.com/CambridgeCentreForProteomics/thp-lopit-2021/blob/main/R/plotLineGraph.R
library("pRoloc")
library("pRolocdata")
data("lpsTimecourse_rep1_mulvey2021")
data("lpsTimecourse_rep2_mulvey2021")
data("lpsTimecourse_rep3_mulvey2021")
x1 <- lpsTimecourse_rep1_mulvey2021
x2 <- lpsTimecourse_rep2_mulvey2021
x3 <- lpsTimecourse_rep3_mulvey2021
lopit_clec_wide <- t(rbind(exprs(x1["Q9Y240",]), exprs(x2["Q9Y240",]),exprs(x3["Q9Y240",])))
lopit_clec_wide <- data.frame(cbind(Time = c(0, 2, 4, 6, 12, 24), lopit_clec_wide))
colnames(lopit_clec_wide)<- c("Time", "X1", "X2", "X6")
lopit_sequ_wide <- t(rbind(exprs(x1["Q13501",]), exprs(x2["Q13501",]),exprs(x3["Q13501",])))
lopit_sequ_wide <- data.frame(cbind(Time = c(0, 2, 4, 6, 12, 24), lopit_sequ_wide))
colnames(lopit_sequ_wide)<- c("Time", "X1", "X2", "X6")
p = plotLineGraph(lopit_clec_wide,
linecol = "#1B83E9",
.ylab = "Abundance\n",
fun = "median") + ggtitle("CLECL11A") +
theme(plot.title = element_text(hjust = 0.5))
q = plotLineGraph(lopit_sequ_wide,
linecol = "#C50000",
.ylab = "Abundance\n",
fun = "median") + ggtitle("Sequestosome") +
theme(plot.title = element_text(hjust = 0.5))
grid.arrange(q, p, ncol = 2)A heatmap of the relative quantitative abundance values for these 15 proteins during the time-course experiment.
library(pRolocdata)
library(pRoloc)
library(gplots)
prots_15 <- c("CLEC11A", "SQSTM1", "PLEK", "CHCHD2", "CKAP2",
"IFI35", "PALM", "SPG21", "CALCOCO2", "MVP",
"TCEB3", "SRP9", "EIF4A1", "DAB2", "ACSL4")
data("lpsTimecourse_mulvey2021")
ind <- match(prots_15, fData(lpsTimecourse_mulvey2021)$GN)
dat <- exprs(lpsTimecourse_mulvey2021)[ind, ]
rownames(dat) <- prots_15
calcMeds <- function(df, .grepName) {
ind <- grep(.grepName, colnames(df))
.df <- df[, ind]
.mean <- rowMedians(.df)
return(.mean)
}
t0 <- calcMeds(dat, "X0.hr")
t2 <- calcMeds(dat, "X2.hr")
t4 <- calcMeds(dat, "X4.hr")
t6 <- calcMeds(dat, "X6.hr")
t12 <- calcMeds(dat, "X12.hr")
t24 <- calcMeds(dat, "X24.hr")
dat_meds <- cbind(t0, t2, t4, t6, t12, t24)
rownames(dat_meds) <- rownames(dat)
colnames(dat_meds) <- c(0, 2, 4, 6, 12, 24)
my_palette <- colorRampPalette(c("#1B83E9", "grey", "#C50000"))(n = 10)
heatmap.2(dat_meds, density.info = "none", trace = "none",
col = my_palette, Colv = NA, dendrogram = "row",
key=TRUE, cexCol = 2, cexRow = 1.3, margin = c(6,8),
lwid=c(.3,1), lhei = c(.16, .6), offsetRow=0.3)Figure 5.4: A heatmap of the relative quantitative abundance values for these 15 proteins during the time-course experiment.
5.1.7 Figure 7
The hyperLOPIT dataset can be used as a scaffold to overlay additional layers of spatial information.
source("r/prettymap.R")
# https://github.com/CambridgeCentreForProteomics/thp-lopit-2021/blob/main/R/prettymap.R
library(pRoloc)
library(pRolocdata)
## set organelle colours
mycol <- c("#88CCEE", "#332288", "#53CAB7", "#0170b4", "#204f20", "#990000",
"#E69F00", "#DDCC77", "#E18493", "#AA4499", "#D55E00", "grey")
setStockcol(mycol)
setUnknownpch(16)
## get data
data("thpLOPIT_unstimulated_mulvey2021")
data("thpLOPIT_lps_mulvey2021")
data <- commonFeatureNames(thpLOPIT_unstimulated_mulvey2021, thpLOPIT_lps_mulvey2021)
unst <- data[[1]]
lps <- data[[2]]
## Generate the t-SNE coords (Figure 4 of [1])
set.seed(399)
tsne_unst <- plot2D(unst, method = "t-SNE", plot = FALSE)
set.seed(399)
tsne_lps <- plot2D(lps, method = "t-SNE", plot = FALSE)
## Overlay temporal clusters
cluster9 <- c("Q6WKZ4", "P10153", "O96028", "Q92766-2", "P16401", "P14635", "Q9Y2X7", "Q99661",
"O75475", "P49715-3", "Q8N2G8", "Q9NQS7", "P46013", "O60341", "Q02252", "Q96AQ6", "Q6PL18",
"P0C0S5", "P45973", "Q96CM8-2", "Q9BSJ8-2", "Q9BW19", "P29372", "Q9P2K3-3", "Q12912", "A0FGR8-2",
"Q14687", "Q96T88-2", "Q14683", "Q13112", "P49454", "Q14005", "O00257", "P11388-4", "Q96JY6-5",
"P40937", "Q9ULW0-2", "Q07065", "O95490-6", "O95067", "Q9BXS6", "Q96BZ4", "Q96C36", "O60256")
cluster11 <- c("P13073", "P42126", "P23219-5", "Q92896-2", "P50440-2", "P54819", "Q9BX68", "P35659", "P55809",
"Q92922", "Q12874", "P09622", "Q96KQ7-2", "P51572-2", "Q15459", "P42765", "P14866", "P10809", "P56181-2",
"Q14978-2", "P12270", "Q86UP2", "P11310-2", "P53597", "P04181", "Q9NX40", "P07954", "P13804", "Q13435", "Q9Y3B7",
"O75251", "P30042", "P56385", "Q99729-3")
cluster17 <- c("Q9Y224", "P35637", "P09429", "P54577", "Q9UBQ7", "P27695", "P06454", "O43707", "P11586", "Q9UNN5",
"Q9UBE0", "P18206", "P51858", "P59998-3", "P50502", "P48595", "Q9BQS8-4", "P23921", "P06733", "P09960",
"P50452", "P04424", "Q02790", "P06737", "O14618", "P06396-2", "P49588", "Q9HB71", "P15121", "Q9Y5Z4",
"Q8N806", "Q6XQN6", "Q9HC38-2", "P28072", "Q14157-5", "P40925-3", "P80723", "Q9BTT0-3", "P00492", "P21399",
"P00918", "P10124", "Q9Y617", "P32119", "Q9H7C9", "Q9Y5Y6", "P07311", "Q53EL6", "P07900-2", "P09211", "P39019",
"Q9H4A4", "O75131", "P04406", "P19338", "O60701", "P30419", "P06744", "Q99598", "Q9NQP4", "O75874", "P35573",
"Q9NZL9", "P31948-2", "Q13442", "P12814", "O75608", "O95834-3", "Q9NQX3-2", "P43487", "P40121", "P52888", "Q99497",
"Q96BW5", "P61923-4", "Q13630")
par(mfrow = c(1, 2))
prettyTSNE_overlay(tsne_lps, lps, fcol = "localisation.pred",
main = "12h-LPS stimulated THP-1 cells", orgOrder = oo,
mainCol = paste0(darken(mycol), 20),
outlineCol = paste0(darken(mycol), 20))
highlightOnPlot(object = tsne_lps, pch = 21, cex = 1.7,
col = mycol[2], bg = lighten(lighten(mycol[2])),
foi = cluster9, lwd = 2,
args = list(lps))
highlightOnPlot(object = tsne_lps, pch = 21, cex = 1.7,
col = darken(mycol[7]), bg = lighten(lighten(mycol[7])),
foi = cluster11, lwd = 2,
args = list(lps))
highlightOnPlot(object = tsne_lps, pch = 21, cex = 1.7,
col = darken(mycol[3]), bg = lighten(lighten(mycol[3])),
foi = cluster17, lwd = 2,
args = list(lps))
## add a legend
myleg <- c(getMarkerClasses(unst), "Unknown", c("Cluster 9", "Cluster 11", "Cluster 17"))
plot(NULL, xaxt='n',yaxt='n',bty='n',ylab='',xlab='', xlim=0:1, ylim=0:1)
legend("topleft", legend = myleg,
col = c(paste0(mycol[1:11], 60), "#D3D3D3", mycol[2], darken(mycol[7]), darken(mycol[3])),
bty = "n",
pch = 19, cex = 1, pt.cex = 1.6, ncol = 1)Figure 5.5: Spatial map of the hyperlOPIT data from 12h-LPS stimulated cells with temporal clusters 9, 11 and 17 overlaid (purple = cluster 9 (chromatin enriched, adj.p-value = 6.9e-10), yellow = cluster 11 (mitochondria enriched, adj.p-value = 9.6e-09), cyan = cluster 17 (cytosol enriched, adj.p-value = 1.8e-13)). A Fisher’s exact test was used to determine that these three clusters were enriched for individual hyperLOPIT organelles.
library("RColorBrewer")
source("r/plotRibbons.R")
# https://github.com/CambridgeCentreForProteomics/thp-lopit-2021/blob/main/R/plotRibbons.R
## Read in MDI clustering results
mdi_rep1 <- read.csv("csv/mdi_clustering_lpsrep1.csv")
mdi_rep2 <- read.csv("csv/mdi_clustering_lpsrep2.csv")
mdi_rep3 <- read.csv("csv/mdi_clustering_lpsrep3.csv")
mdi <- read.csv("csv/mdi_clusters_output.csv")
# get median normalised intensity
dat_mat <- list(data.matrix(mdi_rep1[, -1]),
data.matrix(mdi_rep2[, -1]),
data.matrix(mdi_rep3[, -1]))
av_mat <- apply(simplify2array(dat_mat), c(1,2), median)
rownames(av_mat) <- mdi_rep1[,1]
colnames(av_mat) <- c(0, 2, 4, 6, 12, 24)
## plot clusters of interest
ids <- c(9, 11, 17)
mdi_profs <- sapply(ids, function(z)
av_mat[mdi$Protein.Accession[which(mdi$Cluster.Number == z)], ])
names(mdi_profs) <- paste0("cluster", ids)
## cluster 9, 11 and 17 profiles
par(mfrow = c(1, 3))
ribbonPlot(mdi_profs$cluster9, col = mycol[2], c(0.05, .95),
main = "Cluster 9")
ribbonPlot(mdi_profs$cluster11, col = mycol[7], c(0.05, .95),
main = "Cluster 11")
ribbonPlot(mdi_profs$cluster17, col = mycol[3], c(0.05, .95),
main = "Cluster 17")Figure 5.6: The temporal profiles of the three Bayesian temporal clusters during the 24h-LPS time-course
source("r/foi.R")
source("r/prettymap.R")
# https://github.com/CambridgeCentreForProteomics/thp-lopit-2021/blob/main/R/prettymap.R
# https://github.com/CambridgeCentreForProteomics/thp-lopit-2021/blob/main/R/foi.R
library(pRoloc)
library(pRolocdata)
## set organelle colours
mycol <- c("#88CCEE", "#332288", "#53CAB7", "#0170b4", "#204f20", "#990000",
"#E69F00", "#DDCC77", "#E18493", "#AA4499", "#D55E00", "grey")
setStockcol(mycol)
setUnknownpch(16)
## get data
data("thpLOPIT_unstimulated_mulvey2021")
data("thpLOPIT_lps_mulvey2021")
data <- commonFeatureNames(thpLOPIT_unstimulated_mulvey2021, thpLOPIT_lps_mulvey2021)
unst <- data[[1]]
lps <- data[[2]]
## Generate the t-SNE coords (Figure 4 of [1])
set.seed(399)
tsne_unst <- plot2D(unst, method = "t-SNE", plot = FALSE)
set.seed(399)
tsne_lps <- plot2D(lps, method = "t-SNE", plot = FALSE)
par(mfrow = c(2, 2))
## ========= Protein complexes =========
## =====================================
EIF3 <- c("O00303", "O75821", "O75822", "P55884-2", "P60228", "Q13347", "Q14152", "Q7L2H7", "Q99613", "Q9UBQ5", "Q9Y262")
Coatomer <- c("P61923-4", "O14579", "P35606", "P48444", "P53618", "P53621", "Q9Y678")
YWHA <- c("P27348", "P31946", "P61981", "P62258", "P63104", "Q04917")
ARP2 <- c("O15511", "P59998-3", "O15143", "O15144", "O15145", "Q92747", "Q9BPX5")
MCM <- c("P33991", "P33993", "P49736", "Q14566", "P25205-2", "P33992")
Exocyst <- c("O60645-3", "Q8TAG9", "Q96A65", "Q96KP1", "Q9UPT5", "Q9Y2D4", "O00471", "Q8IYI6")
CNOT <- c("A5YKK6", "O75175", "Q9NZN8", "Q9UIV1")
BORC <- c("Q96B45", "Q969J3", "Q96GS4")
THOC <- c("Q13769", "Q86W42", "Q8NI27", "Q96FV9", "Q86V81")
TRAPPC <- c("O43617", "P48553", "Q7Z392", "Q8IUR0", "Q8WVT3", "Q96Q05-2", "Q9Y296", "Q9Y2L5")
SF3 <- c("O75533", "Q12874", "Q13435", "Q15393", "Q15428", "Q15459", "Q9Y3B4", "Q9BWJ5")
SMC <- c("A6NHR9", "O95347", "Q14683", "Q9NTJ3", "Q9UQE7")
CCT <- c("P17987", "P40227", "P48643", "P50990", "P50991", "P78371", "P49368", "Q99832")
MRPL <- c("O75394", "P09001", "P49406", "P52815", "Q13084", "Q13405", "Q14197", "Q4U2R6", "Q5T653", "Q6P161",
"Q6P1L8", "Q7Z7F7-2", "Q7Z7H8-2", "Q8IXM3", "Q8N5N7", "Q8N983-4", "Q96A35", "Q96DV4", "Q96EL3", "Q96GC5",
"Q9BQ48", "Q9BQC6", "Q9BRJ2", "Q9BYC8", "Q9BYC9", "Q9BYD1", "Q9BYD2", "Q9BYD3", "Q9BYD6", "Q9BZE1", "Q9H0U6","Q9H2W6", "Q9H9J2", "Q9HD33", "Q9NQ50", "Q9NRX2", "Q9NWU5", "Q9NX20", "Q9NYK5", "Q9NZE8", "Q9P015", "Q9P0M9", "Q9Y3B7")
HMGB <- c("O15347", "P05114", "P05204", "P09429", "P26583")
EMC <- c("O43402", "Q15006", "Q5J8M3", "Q5UCC4", "Q8N766", "Q9NPA0", "Q9P0I2")
AP2 <- c("O95782", "P53680", "P63010-2")
## Unstimulated
prettyTSNE_overlay(tsne_unst, unst, fcol = "localisation.pred",
main = "Unstimulated THP-1 cells:\nprotein complexes", orgOrder = oo,
mainCol = paste0((mycol), 30),
outlineCol = paste0(lighten(mycol), 20))
highlightOnPlot(object = tsne_unst, pch = 21, cex = 1.2,
col = "black", bg = "red",
foi = EIF3, lwd = 2,
args = list(unst))
text(x = 15, y = 11, labels = "EIF3", font = 2, col = "red", cex = 1)
highlightOnPlot(object = tsne_unst, pch = 21, cex = 1.2,
col = "black", bg = "cyan",
foi = Coatomer, lwd = 2,
args = list(unst))
text(x = 30, y = 9, labels = "Coatomer", font = 2)
highlightOnPlot(object = tsne_unst, pch = 21, cex = 1.2,
col = "black", bg = "yellow",
foi = YWHA, lwd = 2,
args = list(unst))
text(x = 26, y = -7, labels = "YWHA", font = 2)
highlightOnPlot(object = tsne_unst, pch = 21, cex = 1.2,
col = "black", bg = "green",
foi = MCM, lwd = 2,
args = list(unst))
text(x = 27, y = 15, labels = "MCM", font = 2)
highlightOnPlot(object = tsne_unst, pch = 21, cex = 1.2,
col = "black", bg = "darkkhaki",
foi = ARP2, lwd = 2,
args = list(unst))
text(x = 7, y = 9, labels = "ARP2/3", font = 2)
highlightOnPlot(object = tsne_unst, pch = 21, cex = 1.2,
col = "black", bg = "orange",
foi = Exocyst, lwd = 2,
args = list(unst))
text(x = 10, y = -20, labels = "Exocyst", font = 2)
highlightOnPlot(object = tsne_unst, pch = 21, cex = 1.2,
col = "black", bg = "blue",
foi = CNOT, lwd = 2,
args = list(unst))
text(x = 0, y = 3, labels = "CNOT", font = 2)
highlightOnPlot(object = tsne_unst, pch = 21, cex = 1.2,
col = "black", bg = "magenta",
foi = BORC, lwd = 2,
args = list(unst))
text(x = 4, y = -32, labels = "BORC", font = 2)
highlightOnPlot(object = tsne_unst, pch = 21, cex = 1.2,
col = "black", bg = "coral",
foi = THOC, lwd = 2,
args = list(unst))
text(x = 7, y = 22, labels = "THOC", font = 2)
highlightOnPlot(object = tsne_unst, pch = 21, cex = 1.2,
col = "black", bg = "pink",
foi = TRAPPC, lwd = 2,
args = list(unst))
text(x = 10, y = -5, labels = "TRAPPC", font = 2)
highlightOnPlot(object = tsne_unst, pch = 21, cex = 1.2,
col = "black", bg = "grey",
foi = SF3, lwd = 2,
args = list(unst))
text(x = 20, y = 22, labels = "SF3", font = 2)
highlightOnPlot(object = tsne_unst, pch = 21, cex = 1.2,
col = "black", bg = "darkgreen",
foi = SMC, lwd = 2,
args = list(unst))
text(x = 0, y = 18, labels = "SMC", font = 2)
highlightOnPlot(object = tsne_unst, pch = 21, cex = 1.2,
col = "black", bg = "purple",
foi = CCT, lwd = 2,
args = list(unst))
text(x =22, y = -1, labels = "CCT", font = 2)
highlightOnPlot(object = tsne_unst, pch = 21, cex = 1.2,
col = "black", bg = "darkorchid1",
foi = HMGB, lwd = 2,
args = list(unst))
text(x = -1, y = 29, labels = "HMGB", font = 2)
highlightOnPlot(object = tsne_unst, pch = 21, cex = 1.2,
col = "black", bg = "beige",
foi = AP2, lwd = 2,
args = list(unst))
text(x = -10, y = -28, labels = "AP2", font = 2)
highlightOnPlot(object = tsne_unst, pch = 21, cex = 1.2,
col = "black", bg = "azure4",
foi = EMC, lwd = 2,
args = list(unst))
text(x = -10, y = -5, labels = "EMC", font = 2)
highlightOnPlot(object = tsne_unst, pch = 21, cex = 1.2,
col = "black", bg = "white",
foi = MRPL, lwd = 2,
args = list(unst))
text(x = -25, y = 23, labels = "MRPL", font = 2)
## LPS
prettyTSNE_overlay(tsne_lps, lps,
fcol = "localisation.pred",
main = "12h-LPS stimulated THP-1 cells:\nprotein complexes",
orgOrder = oo, mainCol = paste0((mycol), 30),
outlineCol = paste0(lighten(mycol), 20))
highlightOnPlot(object = tsne_lps, pch = 21, cex = 1.2,
col = "black", bg = "red",
foi = EIF3, lwd = 2,
args = list(lps))
text(x = 17, y = 25, labels = "EIF3", font = 2, col = "red", cex = 1)
highlightOnPlot(object = tsne_lps, pch = 21, cex = 1.2,
col = "black", bg = "cyan",
foi = Coatomer, lwd = 2,
args = list(lps))
text(x = 10, y = 15, labels = "Coatomer", font = 2)
highlightOnPlot(object = tsne_lps, pch = 21, cex = 1.2,
col = "black", bg = "yellow",
foi = YWHA, lwd = 2,
args = list(lps))
text(x = 30, y = 6, labels = "YWHA", font = 2)
highlightOnPlot(object = tsne_lps, pch = 21, cex = 1.2,
col = "black", bg = "green",
foi = MCM, lwd = 2,
args = list(lps))
text(x = 26, y = 20, labels = "MCM", font = 2)
highlightOnPlot(object = tsne_lps, pch = 21, cex = 1.2,
col = "black", bg = "darkkhaki",
foi = ARP2, lwd = 2,
args = list(lps))
text(x = 10, y = 7, labels = "ARP2/3", font = 2)
highlightOnPlot(object = tsne_lps, pch = 21, cex = 1.2,
col = "black", bg = "orange",
foi = Exocyst, lwd = 2,
args = list(lps))
text(x = 9, y = -26, labels = "Exocyst", font = 2)
highlightOnPlot(object = tsne_lps, pch = 21, cex = 1.2,
col = "black", bg = "blue",
foi = CNOT, lwd = 2,
args = list(lps))
text(x = 0, y = 13, labels = "CNOT", font = 2)
highlightOnPlot(object = tsne_lps, pch = 21, cex = 1.2,
col = "black", bg = "magenta",
foi = BORC, lwd = 2,
args = list(lps))
text(x = 12, y = -23, labels = "BORC", font = 2)
highlightOnPlot(object = tsne_lps, pch = 21, cex = 1.2,
col = "black", bg = "coral",
foi = THOC, lwd = 2,
args = list(lps))
text(x = 0, y = 29, labels = "THOC", font = 2)
highlightOnPlot(object = tsne_lps, pch = 21, cex = 1.2,
col = "black", bg = "pink",
foi = TRAPPC, lwd = 2,
args = list(lps))
text(x = 14, y = -4, labels = "TRAPPC", font = 2)
highlightOnPlot(object = tsne_lps, pch = 21, cex = 1.2,
col = "black", bg = "grey",
foi = SF3, lwd = 2,
args = list(lps))
text(x = 5, y = 23, labels = "SF3", font = 2)
highlightOnPlot(object = tsne_lps, pch = 21, cex = 1.2,
col = "black", bg = "darkgreen",
foi = SMC, lwd = 2,
args = list(lps))
text(x = -15, y = 24, labels = "SMC", font = 2)
highlightOnPlot(object = tsne_lps, pch = 21, cex = 1.2,
col = "black", bg = "purple",
foi = CCT, lwd = 2,
args = list(lps))
text(x = 21, y = 12, labels = "CCT", font = 2)
highlightOnPlot(object = tsne_lps, pch = 21, cex = 1.2,
col = "black", bg = "darkorchid1",
foi = HMGB, lwd = 2,
args = list(lps))
text(x = -20, y = 30, labels = "HMGB", font = 2)
highlightOnPlot(object = tsne_lps, pch = 21, cex = 1.2,
col = "black", bg = "beige",
foi = AP2, lwd = 2,
args = list(lps))
text(x = -5, y = -28, labels = "AP2", font = 2)
highlightOnPlot(object = tsne_lps, pch = 21, cex = 1.2,
col = "black", bg = "azure4",
foi = EMC, lwd = 2,
args = list(lps))
text(x = -10, y = -12, labels = "EMC", font = 2)
highlightOnPlot(object = tsne_lps, pch = 21, cex = 1.2,
col = "black", bg = "white",
foi = MRPL, lwd = 2,
args = list(lps))
text(x = -20, y = 11, labels = "MRPL", font = 2)
## ======== Protein-protein interactions =======
## =============================================
CDC42andTRIP10 <- c("P60953", "Q15642")
HGSandTSG101 <- c("O14964", "Q99816")
WASH <- c("Q2M389", "Q12768") # includes: strumpellin and swip
NLRX1andFASTKD5 <- c("Q86UT6", "Q7L8L6")
TOM1 <- c("Q13501", "O60784-2", "Q13137-4") # includes TOM1, SQSTM1, CALCOCO2
NEMO <- c("Q9Y6K9-2", "O14920") # includes IKBKB and IKBKG
PARP9andDTX3L <- c("Q8IXQ6-2", "Q8TDB6")
IFI35andNMI <- c("P80217-2", "Q13287")
IFI16andMNDA <- c("Q16666", "P41218")
prettyTSNE_overlay(tsne_unst, unst,
fcol = "localisation.pred",
main = "Unstimulated THP1-cells:\nprotein-protein interacting partners",
orgOrder = oo,
mainCol = paste0(mycol, 30),
outlineCol = paste0(lighten(mycol), 20))
highlightOnPlot(object = tsne_unst, pch = 21, cex = 1.2,
col = "black", bg = "red",
foi = CDC42andTRIP10, lwd = 2,
args = list(unst))
text(x = 22, y = -8.3, labels = "CDC42", font = 2, col = "black", cex = 1)
text(x = 22, y = -10.3, labels = "TRIP10", font = 2, col = "black", cex = 1)
highlightOnPlot(object = tsne_unst, pch = 21, cex = 1.2,
col = "black", bg = "green",
foi = HGSandTSG101, lwd = 2,
args = list(unst))
text(x = 17.5, y = -5, labels = "HGS", font = 2, col = "black", cex = 1)
text(x = 17.5, y = -3, labels = "TSG101", font = 2, col = "black", cex = 1)
highlightOnPlot(object = tsne_unst, pch = 21, cex = 1.2,
col = "black", bg = "yellow",
foi = WASH, lwd = 2,
args = list(unst))
text(x = 0, y = -6, labels = "Strumpellin", font = 2, col = "black", cex = 1)
text(x = 2, y = -8, labels = "SWIP", font = 2, col = "black", cex = 1)
highlightOnPlot(object = tsne_unst, pch = 21, cex = 1.2,
col = "black", bg = "cadetblue",
foi = NLRX1andFASTKD5, lwd = 2,
args = list(unst))
text(x = -17, y = 14, labels = "NLRX1", font = 2, col = "black", cex = 1)
text(x = -17, y = 16, labels = "FASTKD5", font = 2, col = "black", cex = 1)
highlightOnPlot(object = tsne_unst, pch = 21, cex = 1.2,
col = "black", bg = "orchid1",
foi = TOM1, lwd = 2,
args = list(unst))
text(x = 15, y = -16, labels = "TOM1", font = 2, col = "black", cex = 1)
text(x = 15, y = -18, labels = "SQSTM1", font = 2, col = "black", cex = 1)
text(x = 15, y = -20, labels = "CALCOCO2", font = 2, col = "black", cex = 1)
highlightOnPlot(object = tsne_unst, pch = 21, cex = 1.2,
col = "black", bg = "cyan",
foi = NEMO, lwd = 2,
args = list(unst))
text(x = 25, y = 2, labels = "IKBKG", font = 2, col = "black", cex = 1)
text(x = 13.4, y = 1, labels = "IKBKB", font = 2, col = "black", cex = 1)
highlightOnPlot(object = tsne_unst, pch = 21, cex = 1.2,
col = "black", bg = "bisque3",
foi = PARP9andDTX3L, lwd = 2,
args = list(unst))
text(x = -.5, y = 8.5, labels = "PARP9", font = 2, col = "black", cex = 1)
text(x = 3, y = 14.3, labels = "DTX3L", font = 2, col = "black", cex = 1)
highlightOnPlot(object = tsne_unst, pch = 21, cex = 1.2,
col = "black", bg = "darkgreen",
foi = IFI35andNMI, lwd = 2,
args = list(unst))
text(x = 17, y = 10, labels = "IFI35", font = 2, col = "black", cex = 1)
text(x = 15, y = 8, labels = "NMI", font = 2, col = "black", cex = 1)
highlightOnPlot(object = tsne_unst, pch = 21, cex = 1.2,
col = "black", bg = "magenta",
foi = IFI16andMNDA, lwd = 2,
args = list(unst))
text(x = 3, y = 26, labels = "IFI16", font = 2, col = "black", cex = 1)
text(x = 3, y = 24, labels = "MNDA", font = 2, col = "black", cex = 1)
## LPS
prettyTSNE_overlay(tsne_lps, lps,
fcol = "localisation.pred",
main = "12h-LPS stimulated THP1-cells:\nprotein-protein interacting partners
",
orgOrder = oo,
mainCol = paste0(lighten(mycol), 30),
outlineCol = paste0(lighten(mycol), 20))
highlightOnPlot(object = tsne_lps, pch = 21, cex = 1.2,
col = "black", bg = "red",
foi = CDC42andTRIP10, lwd = 2,
args = list(lps))
text(x = 25.5, y = -22.3, labels = "CDC42", font = 2, col = "black", cex = 1)
text(x = 22.7, y = -4.7, labels = "TRIP10", font = 2, col = "black", cex = 1)
highlightOnPlot(object = tsne_lps, pch = 21, cex = 1.2,
col = "black", bg = "green",
foi = HGSandTSG101, lwd = 2,
args = list(lps))
text(x = 8, y = -6, labels = "HGS", font = 2, col = "black", cex = 1)
text(x = 10, y = -8, labels = "TSG101", font = 2, col = "black", cex = 1)
highlightOnPlot(object = tsne_lps, pch = 21, cex = 1.2,
col = "black", bg = "yellow",
foi = WASH, lwd = 2,
args = list(lps))
text(x = -7, y = -23, labels = "Strumpellin", font = 2, col = "black", cex = 1)
text(x = -7, y = -21, labels = "SWIP", font = 2, col = "black", cex = 1)
highlightOnPlot(object = tsne_lps, pch = 21, cex = 1.2,
col = "black", bg = "cadetblue",
foi = NLRX1andFASTKD5, lwd = 2,
args = list(lps))
text(x = -30, y = -5, labels = "NLRX1", font = 2, col = "black", cex = 1)
text(x = -30, y = -7, labels = "FASTKD5", font = 2, col = "black", cex = 1)
highlightOnPlot(object = tsne_lps, pch = 21, cex = 1.2,
col = "black", bg = "orchid1",
foi = TOM1, lwd = 2,
args = list(lps))
text(x = 26, y = -12, labels = "TOM1", font = 2, col = "black", cex = 1)
text(x = 25, y = -14, labels = "SQSTM1", font = 2, col = "black", cex = 1)
text(x = 25, y = -16, labels = "CALCOCO2", font = 2, col = "black", cex = 1)
highlightOnPlot(object = tsne_lps, pch = 21, cex = 1.2,
col = "black", bg = "cyan",
foi = NEMO, lwd = 2,
args = list(lps))
text(x = 22, y = 12, labels = "IKBKG", font = 2, col = "black", cex = 1)
text(x = 22, y = 10, labels = "IKBKB", font = 2, col = "black", cex = 1)
highlightOnPlot(object = tsne_lps, pch = 21, cex = 1.2,
col = "black", bg = "bisque3",
foi = PARP9andDTX3L, lwd = 2,
args = list(lps))
text(x = 1, y = 16, labels = "PARP9", font = 2, col = "black", cex = 1)
text(x = 0, y = 14, labels = "DTX3L", font = 2, col = "black", cex = 1)
highlightOnPlot(object = tsne_lps, pch = 21, cex = 1.2,
col = "black", bg = "darkgreen",
foi = IFI35andNMI, lwd = 2,
args = list(lps))
text(x = -10, y = 8, labels = "IFI35", font = 2, col = "black", cex = 1)
text(x = -10, y = 4, labels = "NMI", font = 2, col = "black", cex = 1)
highlightOnPlot(object = tsne_lps, pch = 21, cex = 1.2,
col = "black", bg = "magenta",
foi = IFI16andMNDA, lwd = 2,
args = list(lps))
text(x = -9, y = 29, labels = "IFI16", font = 2, col = "black", cex = 1)
text(x = -9, y = 27, labels = "MNDA", font = 2, col = "black", cex = 1)Figure 5.7: Several protein complexes were overlaid onto the hyperLOPIT plot.Protein-protein interaction partner pairs from the literature were shown to co-localise with each other in hyperLOPIT space
5.2 Supplementary Figures
5.2.1 Supplementary Figure 1
library("pRolocdata")
data("lpsTimecourse_mulvey2021")
data("lpsTimecourse_rep1_mulvey2021")
data("lpsTimecourse_rep2_mulvey2021")
data("lpsTimecourse_rep3_mulvey2021")
data("thpLOPIT_lps_mulvey2021")
data("thpLOPIT_lps_rep1_mulvey2021")
data("thpLOPIT_lps_rep2_mulvey2021")
data("thpLOPIT_lps_rep3_mulvey2021")
data("thpLOPIT_unstimulated_mulvey2021")
data("thpLOPIT_unstimulated_rep1_mulvey2021")
data("thpLOPIT_unstimulated_rep2_mulvey2021")
data("thpLOPIT_unstimulated_rep3_mulvey2021")
## lps timecourse
venn.diagram(
x = list(featureNames(lpsTimecourse_rep1_mulvey2021),
featureNames(lpsTimecourse_rep2_mulvey2021),
featureNames(lpsTimecourse_rep3_mulvey2021)),
category.names = c("Replicate 1" , "Replicate 2 " , "Replicate 3"),
filename = "figures/venn_TC_replicates.png",
main = "LPS timecourse: 0-24h",
col=c("#440154ff", '#21908dff', '#D6BA0D'),
fill = c(alpha("#440154ff",0.3), alpha('#21908dff',0.3), alpha('#D6BA0D',0.3)),
fontfamily = "sans",
cat.fontfamily = "sans",
main.fontfamily = "sans",
cat.col = c("#440154ff", '#21908dff', '#D6BA0D'),
output = FALSE
)
## HL unstimulated
venn.diagram(
x = list(featureNames(thpLOPIT_unstimulated_rep1_mulvey2021),
featureNames(thpLOPIT_unstimulated_rep2_mulvey2021),
featureNames(thpLOPIT_unstimulated_rep3_mulvey2021)),
category.names = c("Replicate 1" , "Replicate 2 " , "Replicate 3"),
filename = "figures/venn_HL_unst_replicates.png",
main = "hyperLOPIT: Untreated THP-1 cells",
col=c("#440154ff", '#21908dff', '#D6BA0D'),
fill = c(alpha("#440154ff",0.3), alpha('#21908dff',0.3), alpha('#D6BA0D',0.3)),
fontfamily = "sans",
cat.fontfamily = "sans",
main.fontfamily = "sans",
cat.col = c("#440154ff", '#21908dff', '#D6BA0D'),
output = FALSE
)
# HL LPS
venn.diagram(
x = list(featureNames(thpLOPIT_lps_rep1_mulvey2021),
featureNames(thpLOPIT_lps_rep2_mulvey2021),
featureNames(thpLOPIT_lps_rep3_mulvey2021)),
category.names = c("Replicate 1" , "Replicate 2 " , "Replicate 3"),
filename = "figures/venn_HL_lps_replicates.png",
main = "hyperLOPIT: 12h-LPS stimulated THP-1 cells",
col=c("#440154ff", '#21908dff', '#D6BA0D'),
fill = c(alpha("#440154ff",0.3), alpha('#21908dff',0.3), alpha('#D6BA0D',0.3)),
fontfamily = "sans",
cat.fontfamily = "sans",
main.fontfamily = "sans",
cat.col = c("#440154ff", '#21908dff', '#D6BA0D'),
output = FALSE
)
# HL intersect
venn.diagram(
x = list(featureNames(thpLOPIT_unstimulated_mulvey2021),
featureNames(thpLOPIT_lps_mulvey2021)),
category.names = c("Untreated" , "12h-LPS"),
filename = "figures/venn_HL_conditions.png",
main = "Subset for common proteins: hyperLOPIT conditions",
col=c("#440154ff", '#21908dff'),
fill = c(alpha("#440154ff",0.3), alpha('#21908dff',0.3)),
fontfamily = "sans",
cat.fontfamily = "sans",
main.fontfamily = "sans",
cat.col = c("#440154ff", '#21908dff'),
margin = 0.05,
cat.pos = c(-140, 140),
cat.dist = c(0.05, 0.05)
)
cmn <- commonFeatureNames(thpLOPIT_unstimulated_mulvey2021, thpLOPIT_lps_mulvey2021)
# HL intersect
venn.diagram(
x = list(featureNames(cmn[[1]]),
featureNames(lpsTimecourse_mulvey2021)),
category.names = c("hyperLOPIT" , "Timecourse"),
filename = "figures/venn_HL_TC.png",
main = "Subset for common proteins: hyperLOPIT and timecourse",
col=c("#440154ff", '#21908dff'),
fill = c(alpha("#440154ff",0.3), alpha('#21908dff',0.3)),
fontfamily = "sans",
cat.fontfamily = "sans",
main.fontfamily = "sans",
cat.col = c("#440154ff", '#21908dff'),
margin = 0.05,
cat.pos = c(-140, 140),
cat.dist = c(0.05, 0.05)
)source("r/prettymap.R")
# https://github.com/CambridgeCentreForProteomics/thp-lopit-2021/blob/main/R/prettymap.R
library(pRoloc)
library(pRolocdata)
data("thpLOPIT_lps_mulvey2021")
cytokines <- readRDS("data/cytokine_msnset.rds")
## PLot cytokines
"IL1B" <- "P01584"
"CXCL10" <- "P02778"
"IL8" <- "P10145"
"TNF" <- "P01375"
mycol <- c("#88CCEE", "#332288", "#53CAB7", "#0170b4", "#204f20", "#990000",
"#E69F00", "#DDCC77", "#E18493", "#AA4499", "#D55E00", "grey")
oo = c(1:3, 10, 5, 4, 6:7, 9, 8, 11) ## specify order in which to plot organelles
set.seed(399)
tsne_cytokines <- plot2D(cytokines, method = "t-SNE",plot = FALSE)
tsne_cytokines <- tsne_cytokines[, c(2, 1)]
tsne_cytokines <- tsne_cytokines*-1
## match protein ids and map to cytokine data
.ma <- match(featureNames(thpLOPIT_lps_mulvey2021), featureNames(cytokines))
fData(cytokines)$res <- "unknown"
fData(cytokines)$res[.ma] <- fData(thpLOPIT_lps_mulvey2021)$localisation.pred
par(mfrow = c(1, 2))
prettyTSNE_overlay(tsne_cytokines,
cytokines,
main = "Supplementary Figure 1F - cytokines", orgOrder = oo,
fcol = "res",
mainCol = paste0(lighten(mycol), 40),
outlineCol = paste0(mycol, 40))
highlightOnPlot(object = tsne_cytokines, pch = 24, cex = 2,
col = "black", bg = "red",
foi = IL1B, lwd = 3,
args = list(cytokines))
text(20,-2.5, "IL1B", lwd = 4, cex = 1.3, font = 2)
highlightOnPlot(object = tsne_cytokines, pch = 24, cex = 2,
col = "black", bg = "red",
foi = IL8, lwd = 3,
args = list(cytokines))
text(-10.5,-11.7, "IL8", lwd = 4, cex = 1.3, font = 2)
highlightOnPlot(object = tsne_cytokines, pch = 24, cex = 2,
col = "black", bg = "red",
foi = CXCL10, lwd = 3,
args = list(cytokines))
text(10,-23, "CXCL10", lwd = 4, cex = 1.3, font = 2)
highlightOnPlot(object = tsne_cytokines, pch = 24, cex = 2,
col = "black", bg = "red",
foi = TNF, lwd = 3,
args = list(cytokines))
text(0,-17, "TNF", lwd = 4, cex = 1.3, font = 2)
## add a legend
myleg <- c(getMarkerClasses(cytokines), "Unknown")
plot(NULL, xaxt='n',yaxt='n',bty='n',ylab='',xlab='', xlim=0:1, ylim=0:1)
legend("topleft", legend = myleg, col = mycol, bty = "n",
pch = 19, cex = 1, pt.cex = 1.6, ncol = 1)Figure 5.8: t-SNE spatial map showing the localisation of four cytokine proteins that were imputed from incomplete TMT profiles and overlaid onto the LPS stimulated hyperLOPIT map, to give an indication of their steady state localiation.
source("R/intersection.R")
## Add a label to the LPS dataset so when we combine it
## with the unstimulated the information is not lost
.lps <- lps
.lps <- updateFvarLabels(.lps, "LPS")
cmb <- MSnbase::combine(unst, .lps) # now combine all results
df_all <- compareDatasets(cmb,
fcol1 = "localisation.pred",
fcol2 = "localisation.pred.LPS")
ggheatmap(df_all, title = "TAGM locations between conditions")5.2.2 Supplementary Figure 2
source("r/prettymap.R")
source("r/foi.R")
# https://github.com/CambridgeCentreForProteomics/thp-lopit-2021/blob/main/R/prettymap.R
# https://github.com/CambridgeCentreForProteomics/thp-lopit-2021/blob/main/R/foi.R
library(pRoloc)
library(pRolocdata)
## set organelle colours
mycol <- c("#88CCEE", "#332288", "#53CAB7", "#0170b4", "#204f20", "#990000",
"#E69F00", "#DDCC77", "#E18493", "#AA4499", "#D55E00", "grey")
setStockcol(mycol)
setUnknownpch(16)
## get data
data("thpLOPIT_unstimulated_mulvey2021")
data("thpLOPIT_lps_mulvey2021")
data <- commonFeatureNames(thpLOPIT_unstimulated_mulvey2021, thpLOPIT_lps_mulvey2021)## 3288 features in common
unst <- data[[1]]
lps <- data[[2]]
## Generate the t-SNE coords (Figure 4 of [1])
set.seed(399)
tsne_unst <- plot2D(unst, method = "t-SNE", plot = FALSE)
set.seed(399)
tsne_lps <- plot2D(lps, method = "t-SNE", plot = FALSE)
par(mfrow = c(2, 2))
## Unstimulated
prettyTSNE_overlay(tsne_unst, unst,
fcol = "localisation.pred",
main = "Unstimulated THP-1 cells:\ntranslocation events",
orgOrder = oo,
mainCol = paste0(lighten(mycol), 30),
outlineCol = paste0(lighten(mycol), 30))
highlightOnPlot(object = tsne_unst, pch = 21, cex = 1.7,
col = mycol[2], bg = lighten(lighten("grey")),
foi = type1, lwd = 2,
args = list(unst))
highlightOnPlot(object = tsne_unst, pch = 24, cex = 1.7,
col = darken(mycol[7]), bg = lighten(lighten("#f4f4c8")),
foi = type2, lwd = 2,
args = list(unst))
highlightOnPlot(object = tsne_unst, pch = 21, cex = 1.7,
col = darken("purple"), bg = lighten(lighten("#f2a6e3")),
foi = type3, lwd = 2,
args = list(unst))
highlightOnPlot(object = tsne_unst, pch = 24, cex = 1.7,
col = "#1c1c78", bg = lighten(lighten("#5fa8cc")),
foi = type4, lwd = 2,
args = list(unst))
prettyTSNE_overlay(tsne_lps, lps, fcol = "localisation.pred",
main = "12h-LPS stimulated cells:\ntranslocation events",
orgOrder = oo,
mainCol = paste0(lighten(mycol), 30),
outlineCol = paste0(lighten(mycol), 30))
highlightOnPlot(object = tsne_lps, pch = 21, cex = 1.7,
col = mycol[2], bg = lighten(lighten("grey")),
foi = type1, lwd = 2,
args = list(lps))
highlightOnPlot(object = tsne_lps, pch = 24, cex = 1.7,
col = darken(mycol[7]), bg = lighten(lighten("#f4f4c8")),
foi = type2, lwd = 2,
args = list(lps))
highlightOnPlot(object = tsne_lps, pch = 21, cex = 1.7,
col = darken("purple"), bg = lighten(lighten("#f2a6e3")),
foi = type3, lwd = 2,
args = list(lps))
highlightOnPlot(object = tsne_lps, pch = 24, cex = 1.7,
col = "#1c1c78", bg = lighten(lighten("#5fa8cc")),
foi = type4, lwd = 2,
args = list(lps))
plot(NULL, xaxt='n',yaxt='n',bty='n',ylab='',xlab='', xlim=0:1, ylim=0:1)
legend("topleft", legend = c("Type 1: organelle-to-organelle",
"Type 2: unknown-to-organelle",
"Type 3: organelle-to-unknown",
"Type 4: unknown-to-unknown"),
col = c(mycol[2], darken(mycol[7]), darken("purple"), "#1c1c78"),
pt.bg = c(lighten(lighten("grey")), lighten(lighten("#f4f4c8")),
lighten(lighten("#f2a6e3")), lighten(lighten("#5fa8cc"))),
bty = "n",
pch = c(21, 24, 21, 24), pt.cex = 1.6, cex = 1)
## add a legend
myleg <- c(getMarkerClasses(lps), "Unknown")
plot(NULL, xaxt='n',yaxt='n',bty='n',ylab='',xlab='', xlim=0:1, ylim=0:1)
legend("topleft", legend = myleg, col = mycol, bty = "n",
pch = 19, cex = 1, pt.cex = 1.6, ncol = 1)Figure 5.9: t-SNE map showing the 253 translocating proteins from the hyperLOPIT experiments and plotted by translocation class.
source("R/circos.R")
# https://github.com/CambridgeCentreForProteomics/thp-lopit-2021/blob/main/R/circos.R
library("pRoloc")
library("pRolocdata")
## set organelle colours
mycol <- c("#88CCEE", "#332288", "#53CAB7", "#0170b4", "#204f20", "#990000",
"#E69F00", "#DDCC77", "#E18493", "#AA4499", "#D55E00", "grey")
setStockcol(mycol)
setUnknownpch(16)
## get data
data("thpLOPIT_unstimulated_mulvey2021")
data("thpLOPIT_lps_mulvey2021")
data <- commonFeatureNames(thpLOPIT_unstimulated_mulvey2021, thpLOPIT_lps_mulvey2021)
unst <- data[[1]]
lps <- data[[2]]
fData(unst)$translocations <- fData(lps)$translocations <- NA
fData(unst)$translocations[which(fData(unst)$type1_translocation)] <-
fData(lps)$translocations[which(fData(lps)$type1_translocation)] <- "type1"
fData(unst)$translocations[which(fData(unst)$type2_translocation)] <-
fData(lps)$translocations[which(fData(lps)$type2_translocation)] <- "type2"
fData(unst)$translocations[which(fData(unst)$type3_translocation)] <-
fData(lps)$translocations[which(fData(lps)$type3_translocation)] <- "type3"
fData(unst)$translocations[which(fData(unst)$type4_translocation)] <-
fData(lps)$translocations[which(fData(lps)$type4_translocation)] <- "type4"
## generate my colour scheme
circos_cols <- c(getStockcol(), "grey")
orgs <- c(union(getMarkerClasses(unst), getMarkerClasses(lps)), "unknown")
colscheme <- setNames(circos_cols, orgs) # check levels consistent
## get indices of translocating proteins
tl <- !is.na(fData(unst)$translocations)
## set circos plot parameters
par(mar = c(5, 5, 5, 5), cex = .5, mfrow = c(1,1))
circos.clear()
circos.par(gap.degree = 4)
## plot circos
customChord(unst[tl, ], lps[tl, ],
cols = colscheme,
diffHeight = -0.02,
transparency = 0.3,
link.sort = FALSE,
labels = TRUE)Figure 5.10: Circos plot showing the flow of translocating proteins between different subcellular compartments.
Note: labels were optimised in Inkscape
source("r/prettymap.R")
source("r/foi.R")
# https://github.com/CambridgeCentreForProteomics/thp-lopit-2021/blob/main/R/prettymap.R
# https://github.com/CambridgeCentreForProteomics/thp-lopit-2021/blob/main/R/foi.R
library(pRoloc)
library(pRolocdata)
## set organelle colours
mycol <- c("#88CCEE", "#332288", "#53CAB7", "#0170b4", "#204f20", "#990000",
"#E69F00", "#DDCC77", "#E18493", "#AA4499", "#D55E00", "grey")
setStockcol(mycol)
setUnknownpch(16)
## get data
data("thpLOPIT_unstimulated_mulvey2021")
data("thpLOPIT_lps_mulvey2021")
data <- commonFeatureNames(thpLOPIT_unstimulated_mulvey2021, thpLOPIT_lps_mulvey2021)
unst <- data[[1]]
lps <- data[[2]]
## Generate the t-SNE coords (Figure 4 of [1])
set.seed(399)
tsne_unst <- plot2D(unst, method = "t-SNE", plot = FALSE)
set.seed(399)
tsne_lps <- plot2D(lps, method = "t-SNE", plot = FALSE)
## ===========Cytosolic movers============
par(mfrow = c(3,2))
prettyTSNE_overlay(tsne_unst, unst,
fcol = "localisation.pred",
main = "Cytosolic translocations (67 proteins)",
orgOrder = oo,
mainCol = paste0(lighten(mycol), 30),
outlineCol = paste0(lighten(mycol), 30))
highlightOnPlot(object = tsne_unst, pch = 8, cex = 1.7,
col = "black", bg = "black",
foi = cytosol, lwd = 2,
args = list(unst))
prettyTSNE_overlay(tsne_lps, lps,
fcol = "localisation.pred", main = "",
orgOrder = oo,
mainCol = paste0(lighten(mycol), 30),
outlineCol = paste0(lighten(mycol), 30))
highlightOnPlot(object = tsne_lps, pch = 8, cex = 1.7,
col = "black", bg = "black",
foi = cytosol, lwd = 2,
args = list(lps))(mfrow = c(2, 2))
## ===========Nuclear movers============
prettyTSNE_overlay(tsne_unst, unst,
fcol = "localisation.pred",
main = "Nuclear translocations (57 proteins)",
orgOrder = oo,
mainCol = paste0(lighten(mycol), 30),
outlineCol = paste0(lighten(mycol), 30))
highlightOnPlot(object = tsne_unst, pch = 8, cex = 1.7,
col = "black", bg = "black",
foi = nuclear, lwd = 2,
args = list(unst))
prettyTSNE_overlay(tsne_lps, lps, fcol = "localisation.pred",
main = "", orgOrder = oo,
mainCol = paste0(lighten(mycol), 30),
outlineCol = paste0(lighten(mycol), 30))
highlightOnPlot(object = tsne_lps, pch = 8, cex = 1.7,
col = "black", bg = "black",
foi = nuclear, lwd = 2,
args = list(lps))
## ===========Lysosomal movers============
prettyTSNE_overlay(tsne_unst, unst,
fcol = "localisation.pred",
main = "Lysosomal translocations (49 proteins)",
orgOrder = oo,
mainCol = paste0(lighten(mycol), 30),
outlineCol = paste0(lighten(mycol), 30))
highlightOnPlot(object = tsne_unst, pch = 8, cex = 1.7,
col = "black", bg = "black",
foi = lysosome, lwd = 2,
args = list(unst))
prettyTSNE_overlay(tsne_lps, lps, fcol = "localisation.pred",
main = "", orgOrder = oo,
mainCol = paste0(lighten(mycol), 30),
outlineCol = paste0(lighten(mycol), 30))
highlightOnPlot(object = tsne_lps, pch = 8, cex = 1.7,
col = "black", bg = "black",
foi = lysosome, lwd = 2,
args = list(lps))5.2.3 Supplementary Figure 3
- Shown are 37 proteins which were found to translocate between the cytosol and the nuclear clusters.
- Shown are 9 proteins found to translocate between subnuclear compartments.
- Shown are 70 proteins found to translocate to or from the PM.
- Shown are three proteins known to co-localise: SQSTM1, CALCOCO2, TOM1.
source("r/prettymap.R")
source("r/foi.R")
# https://github.com/CambridgeCentreForProteomics/thp-lopit-2021/blob/main/R/prettymap.R
# https://github.com/CambridgeCentreForProteomics/thp-lopit-2021/blob/main/R/foi.R
library(pRoloc)
library(pRolocdata)
## set organelle colours
mycol <- c("#88CCEE", "#332288", "#53CAB7", "#0170b4", "#204f20", "#990000",
"#E69F00", "#DDCC77", "#E18493", "#AA4499", "#D55E00", "grey")
setStockcol(mycol)
setUnknownpch(16)
## get data
data("thpLOPIT_unstimulated_mulvey2021")
data("thpLOPIT_lps_mulvey2021")
data <- commonFeatureNames(thpLOPIT_unstimulated_mulvey2021, thpLOPIT_lps_mulvey2021)
unst <- data[[1]]
lps <- data[[2]]
## Generate the t-SNE coords (Figure 4 of [1])
set.seed(399)
tsne_unst <- plot2D(unst, method = "t-SNE", plot = FALSE)
set.seed(399)
tsne_lps <- plot2D(lps, method = "t-SNE", plot = FALSE)
par(mfrow = c(4,2))
## ================ Cytosol to nucleus=====================
prettyTSNE_overlay(tsne_unst, unst,
fcol = "localisation.pred",
main = "Cytosol to nucleus translocations",
orgOrder = oo,
mainCol = paste0(lighten(mycol), 30),
outlineCol = paste0(lighten(mycol), 30))
highlightOnPlot(object = tsne_unst, pch = 21, cex = 1.7,
col = "black", bg = "grey",
foi = nucleocyto, lwd = 2,
args = list(unst))
highlightOnPlot(object = tsne_unst, pch = 21, cex = 1.7,
col = "black", bg = "red2",
foi = EIF3, lwd = 2,
args = list(unst))
prettyTSNE_overlay(tsne_lps, lps,
fcol = "localisation.pred",
main = "",
orgOrder = oo,
mainCol = paste0(lighten(mycol), 30),
outlineCol = paste0(lighten(mycol), 30))
highlightOnPlot(object = tsne_lps, pch = 21, cex = 1.7,
col = "black", bg = "grey",
foi = nucleocyto, lwd = 2,
args = list(lps))
highlightOnPlot(object = tsne_lps, pch = 21, cex = 1.7,
col = "black", bg = "red2",
foi = EIF3, lwd = 2,
args = list(lps))
## ===========Subnuclear translocations=============
prettyTSNE_overlay(tsne_unst, unst,
fcol = "localisation.pred",
main = "Subnuclear translocations",
orgOrder = oo,
mainCol = paste0(lighten(mycol), 30),
outlineCol = paste0(lighten(mycol), 30))
highlightOnPlot(object = tsne_unst, pch = 24, cex = 1.7,
col = "black", bg = "red3",
foi = subnuc, lwd = 3,
args = list(unst))
text(x = -5, y = 23, labels = "CTDSPL1", font = 2, col = "black", cex = 1)
text(x = -5, y = 18, labels = "TCEB3", font = 2, col = "black", cex = 1)
text(x = -5, y = 0, labels = "MAP7D3", font = 2, col = "black", cex = 1)
text(x = -10, y = 20, labels = "CKAP2", font = 2, col = "black", cex = 1)
text(x = 4, y = 21, labels = "PHF3", font = 2, col = "black", cex = 1)
text(x = 12, y = 4, labels = "PAXX", font = 2, col = "black", cex = 1)
text(x = -1, y = -2, labels = "EML4", font = 2, col = "black", cex = 1)
text(x = 5, y = 19, labels = "SEPT11", font = 2, col = "black", cex = 1)
text(x = 10, y = 28, labels = "RRP15", font = 2, col = "black", cex = 1)
prettyTSNE_overlay(tsne_lps, lps,
fcol = "localisation.pred",
main = "", orgOrder = oo,
mainCol = paste0(lighten(mycol), 30),
outlineCol = paste0(lighten(mycol), 30))
highlightOnPlot(object = tsne_lps, pch = 24, cex = 1.7,
col = "black", bg = "red3",
foi = subnuc, lwd = 3,
args = list(lps))
text(x = -22, y = 23, labels = "CTDSPL1", font = 2, col = "black", cex = 1)
text(x = -21, y = 21, labels = "TCEB3", font = 2, col = "black", cex = 1)
text(x = 3, y = 7, labels = "MAP7D3", font = 2, col = "black", cex = 1)
text(x = -18, y = 25, labels = "CKAP2", font = 2, col = "black", cex = 1)
text(x = -6, y = 26, labels = "PHF3", font = 2, col = "black", cex = 1)
text(x = 0, y = 14, labels = "EML4", font = 2, col = "black", cex = 1)
text(x = -10, y = 19, labels = "SEPT11", font = 2, col = "black", cex = 1)
text(x = -4, y = 28, labels = "RRP15", font = 2, col = "black", cex = 1)
## ===========PM translocations=============
prettyTSNE_overlay(tsne_unst, unst,
fcol = "localisation.pred",
main = "Plasma membrane translocations",
orgOrder = oo,
mainCol = paste0(lighten(mycol), 30),
outlineCol = paste0(lighten(mycol), 30))
highlightOnPlot(object = tsne_unst, pch = 21, cex = 1.7,
col = "black", bg = "grey",
foi = PM, lwd = 2,
args = list(unst))
prettyTSNE_overlay(tsne_lps, lps, fcol = "localisation.pred",
main = "", orgOrder = oo,
mainCol = paste0(lighten(mycol), 30),
outlineCol = paste0(lighten(mycol), 30))
highlightOnPlot(object = tsne_lps, pch = 21, cex = 1.7,
col = "black", bg = "grey",
foi = PM, lwd = 2,
args = list(lps))
## ===========Autophagy translocations=============
prettyTSNE_overlay(tsne_unst, unst,
fcol = "localisation.pred",
main = "Autophagy machinery",
orgOrder = oo,
mainCol = paste0(lighten(mycol), 30),
outlineCol = paste0(lighten(mycol), 30))
highlightOnPlot(object = tsne_unst, pch = 24, cex = 2,
col = "black", bg = "red3",
foi = autophagy, lwd = 3,
args = list(unst))
text(x = 22, y = -11, labels = "SQSTM1", font = 2, col = "black", cex = 1)
text(x = 22, y = -15, labels = "CALCOCO2", font = 2, col = "black", cex = 1)
text(x = 22, y = -13, labels = "TOM1", font = 2, col = "black", cex = 1)
prettyTSNE_overlay(tsne_lps, lps,
fcol = "localisation.pred",
main = "", orgOrder = oo,
mainCol = paste0(lighten(mycol), 30),
outlineCol = paste0(lighten(mycol), 30))
highlightOnPlot(object = tsne_lps, pch = 24, cex = 2,
col = "black", bg = "red3",
foi = autophagy, lwd = 3,
args = list(lps))
text(x = 20, y = -14, labels = "SQSTM1", font = 2, col = "black", cex = 1)
text(x = 20, y = -18, labels = "CALCOCO2", font = 2, col = "black", cex = 1)
text(x = 20, y = -16, labels = "TOM1", font = 2, col = "black", cex = 1)Figure 5.11: Summary of nucleo-cytoplasmic and plasma membrane translocation events. (A) Shown are 37 proteins which were found to translocate between the cytosol and the nuclear clusters. (B) Shown are 9 proteins found to translocate between subnuclear compartments. (C) Shown are 70 proteins found to translocate to or from the PM. (D) Shown are three proteins known to co-localise: SQSTM1, CALCOCO2, TOM1
5.2.4 Supplementary Figure 4
source("r/prettymap.R")
source("r/foi.R")
# https://github.com/CambridgeCentreForProteomics/thp-lopit-2021/blob/main/R/prettymap.R
# https://github.com/CambridgeCentreForProteomics/thp-lopit-2021/blob/main/R/foi.R
library(pRoloc)
library(pRolocdata)
## set organelle colours
mycol <- c("#88CCEE", "#332288", "#53CAB7", "#0170b4", "#204f20", "#990000",
"#E69F00", "#DDCC77", "#E18493", "#AA4499", "#D55E00", "grey")
setStockcol(mycol)
setUnknownpch(16)
## get data
data("thpLOPIT_unstimulated_mulvey2021")
data("thpLOPIT_lps_mulvey2021")
data <- commonFeatureNames(thpLOPIT_unstimulated_mulvey2021, thpLOPIT_lps_mulvey2021)## 3288 features in common
unst <- data[[1]]
lps <- data[[2]]
## Generate the t-SNE coords (Figure 4 of [1])
set.seed(399)
tsne_unst <- plot2D(unst, method = "t-SNE", plot = FALSE)
set.seed(399)
tsne_lps <- plot2D(lps, method = "t-SNE", plot = FALSE)
## ==================== Trafficking proteins===================
par(mfrow = c(3,2))
prettyTSNE_overlay(tsne_unst, unst, fcol = "localisation.pred", orgOrder = oo,
mainCol = paste0(lighten(mycol), 40),
outlineCol = paste0((mycol), 40),
cex = 2, main = "(A) Trafficking proteins")
highlightOnPlot(object = tsne_unst, pch = 21, cex = 2.2,
col = "black", bg = "gray",
foi = traff, lwd = 2.4,
args = list(unst))
text(x = 11, y = -16, labels = "CHMP2B", font = 2, col = "black", cex = 1)
text(x = -13, y = -23, labels = "SV2A", font = 2, col = "black", cex = 1)
text(x = 12, y = -2, labels = "TRAPPC3", font = 2, col = "black", cex = 1)
text(x = 7, y = -4, labels = "AP1G1", font = 2, col = "black", cex = 1)
text(x = 12, y = -6, labels = "strumpellin", font = 2, col = "black", cex = 1)
text(x = 16, y = -4, labels = "IST1", font = 2, col = "black", cex = 1)
text(x = 10, y = -18, labels = "SYTL4", font = 2, col = "black", cex = 1)
text(x = 6, y = -35, labels = "SCAMP2", font = 2, col = "black", cex = 1)
prettyTSNE_overlay(tsne_lps, lps, fcol = "localisation.pred", orgOrder = oo,
mainCol = paste0(lighten(mycol), 40),
outlineCol = paste0((mycol), 40),
cex = 2, main = "")
highlightOnPlot(object = tsne_lps, pch = 21, cex = 2.2,
col = "black", bg = "gray",
foi = traff, lwd = 2.4,
args = list(lps))
text(x = 14, y = -16, labels = "CHMP2B", font = 2, col = "black", cex = 1)
text(x = 13, y = -14, labels = "SV2A", font = 2, col = "black", cex = 1)
text(x = 16, y = -8, labels = "TRAPPC3", font = 2, col = "black", cex = 1)
text(x = 3, y = -2, labels = "AP1G1", font = 2, col = "black", cex = 1)
text(x = -18, y = -19, labels = "strumpellin", font = 2, col = "black", cex = 1)
text(x = -5, y = -25, labels = "IST1", font = 2, col = "black", cex = 1)
text(x = 0, y = -13, labels = "SYTL4", font = 2, col = "black", cex = 1)
text(x = 5, y = -19, labels = "SCAMP2", font = 2, col = "black", cex = 1)
## ===================RABs========================
prettyTSNE_overlay(tsne_unst, unst, fcol = "localisation.pred", orgOrder = oo,
mainCol = paste0(lighten(mycol), 40),
outlineCol = paste0((mycol), 40),
cex = 2, main = "(B) RAB GTPase translocating proteins")
highlightOnPlot(object = tsne_unst, pch = 21, cex = 2.2,
col = "black", bg = "gray",
foi = RABs, lwd = 2.4,
args = list(unst))
text(x = 10, y = -30, labels = "RAB23", font = 2, col = "black", cex = 1)
text(x = 3, y = -13, labels = "RAB6B", font = 2, col = "black", cex = 1)
text(x = -9, y = -14, labels = "RAB9A", font = 2, col = "black", cex = 1)
text(x = -17, y = -18, labels = "RAB31", font = 2, col = "black", cex = 1)
text(x = -2, y = -18, labels = "RAB7A", font = 2, col = "black", cex = 1)
text(x = -3, y = -20, labels = "RAB8A", font = 2, col = "black", cex = 1)
text(x = -3, y = -22, labels = "RAB1C", font = 2, col = "black", cex = 1)
text(x = -5, y = -10, labels = "RAB5A", font = 2, col = "black", cex = 1)
text(x = 10, y = -6, labels = "RAB4A", font = 2, col = "black", cex = 1)
text(x = 15, y = -4, labels = "RAB4B", font = 2, col = "black", cex = 1)
text(x = 15, y = -2, labels = "RAB14", font = 2, col = "black", cex = 1)
text(x = 15, y = -0, labels = "RAB32", font = 2, col = "black", cex = 1)
prettyTSNE_overlay(tsne_lps, lps, fcol = "localisation.pred", orgOrder = oo,
mainCol = paste0(lighten(mycol), 40),
outlineCol = paste0((mycol), 40),
cex = 2, main = "")
highlightOnPlot(object = tsne_lps, pch = 21, cex = 2.2,
col = "black", bg = "gray",
foi = RABs, lwd = 2.4,
args = list(lps))
text(x = 21, y = -20, labels = "RAB23", font = 2, col = "black", cex = 1)
text(x = 20, y = -11, labels = "RAB6B", font = 2, col = "black", cex = 1)
text(x = 10, y = -2, labels = "RAB9A", font = 2, col = "black", cex = 1)
text(x = 2, y = -20, labels = "RAB31", font = 2, col = "black", cex = 1)
text(x = 2, y = -22, labels = "RAB7A", font = 2, col = "black", cex = 1)
text(x = 3, y = -15, labels = "RAB8A", font = 2, col = "black", cex = 1)
text(x = -8, y = -13, labels = "RAB1C", font = 2, col = "black", cex = 1)
text(x = 6, y = -18, labels = "RAB5A", font = 2, col = "black", cex = 1)
text(x = 0, y = -26, labels = "RAB4A", font = 2, col = "black", cex = 1)
text(x = -8, y = -19, labels = "RAB4B", font = 2, col = "black", cex = 1)
text(x = 0, y = -28, labels = "RAB14", font = 2, col = "black", cex = 1)
text(x = -18, y = -23, labels = "RAB32", font = 2, col = "black", cex = 1)
## ====================ESCRT complex===================================
prettyTSNE_overlay(tsne_unst, unst, fcol = "localisation.pred", orgOrder = oo,
mainCol = paste0(lighten(mycol), 40),
outlineCol = paste0((mycol), 20),
cex = 2, main = "(C) ESCRT complex proteins")
highlightOnPlot(object = tsne_unst, pch = 21, cex = 2.2,
col = "black", bg = "gray",
foi = ESCRT, lwd = 2.4,
args = list(unst))
text(x = 17.3, y = 1.5, labels = "CHMP4A", font = 2, col = "black", cex = 1)
text(x = 25.5, y = -3, labels = "VTA1", font = 2, col = "black", cex = 1)
text(x = 27, y = -9, labels = "CHMP4B", font = 2, col = "black", cex = 1)
text(x = 26.3, y = -11, labels = "CHMP5", font = 2, col = "black", cex = 1)
text(x = 6, y = -5, labels = "IST1", font = 2, col = "black", cex = 1)
text(x = 6, y = -7, labels = "CHMP2A", font = 2, col = "black", cex = 1)
text(x = 6, y = -9, labels = "VPS4A", font = 2, col = "black", cex = 1)
text(x = -9, y = -12, labels = "SPAST", font = 2, col = "black", cex = 1)
text(x = -7, y = -15, labels = "CHMP1A", font = 2, col = "black", cex = 1)
text(x = -7, y = -17, labels = "CHMP1B", font = 2, col = "black", cex = 1)
text(x = 5, y = -18.5, labels = "CHMP2B", font = 2, col = "black", cex = 1)
prettyTSNE_overlay(tsne_lps, lps, fcol = "localisation.pred", orgOrder = oo,
mainCol = paste0(lighten(mycol), 40),
outlineCol = paste0((mycol), 20),
cex = 2, main = "")
highlightOnPlot(object = tsne_lps, pch = 21, cex = 2.2,
col = "black", bg = "gray",
foi = ESCRT, lwd = 2.4,
args = list(lps))
text(x = 10, y = 0, labels = "CHMP4A", font = 2, col = "black", cex = 1)
text(x = 18, y = 1.5, labels = "VTA1", font = 2, col = "black", cex = 1)
text(x = 20, y = -5.5, labels = "CHMP4B", font = 2, col = "black", cex = 1)
text(x = 19.3, y = -7.5, labels = "CHMP5", font = 2, col = "black", cex = 1)
text(x = 0.6, y = -27, labels = "IST1", font = 2, col = "black", cex = 1)
text(x = -2, y = -10, labels = "CHMP2A", font = 2, col = "black", cex = 1)
text(x = -2, y = -12, labels = "VPS4A", font = 2, col = "black", cex = 1)
text(x = -2, y = -14, labels = "SPAST", font = 2, col = "black", cex = 1)
text(x = -2, y = -16, labels = "CHMP1A", font = 2, col = "black", cex = 1)
text(x = -2, y = -18, labels = "CHMP1B", font = 2, col = "black", cex = 1)
text(x = -2, y = -20, labels = "CHMP2B", font = 2, col = "black", cex = 1)Figure 5.12: T-SNE plots of translocating proteins involved in trafficking. (A) Shown are 8 trafficking proteins which were found to translocate following LPS stimulation. (B) Shown are 12 RAB GTPase trafficking proteins which were found to translocate following LPS stimulation. (C) 11 members of the ESCRT complex.
5.2.5 Supplementary Figure 5
source("r/prettymap.R")
source("r/foi.R")
# https://github.com/CambridgeCentreForProteomics/thp-lopit-2021/blob/main/R/prettymap.R
# https://github.com/CambridgeCentreForProteomics/thp-lopit-2021/blob/main/R/foi.R
library(pRoloc)
library(pRolocdata)
## set organelle colours
mycol <- c("#88CCEE", "#332288", "#53CAB7", "#0170b4", "#204f20", "#990000",
"#E69F00", "#DDCC77", "#E18493", "#AA4499", "#D55E00", "grey")
setStockcol(mycol)
setUnknownpch(16)
## get data
data("thpLOPIT_unstimulated_mulvey2021")
data("thpLOPIT_lps_mulvey2021")
data <- commonFeatureNames(thpLOPIT_unstimulated_mulvey2021, thpLOPIT_lps_mulvey2021)## 3288 features in common
unst <- data[[1]]
lps <- data[[2]]
## Generate the t-SNE coords (Figure 4 of [1])
set.seed(399)
tsne_unst <- plot2D(unst, method = "t-SNE", plot = FALSE)
set.seed(399)
tsne_lps <- plot2D(lps, method = "t-SNE", plot = FALSE)
par(mfrow = c(4, 2))
prettyTSNE_overlay(tsne_unst, unst, fcol = "localisation.pred", orgOrder = oo,
mainCol = paste0(lighten(mycol), 80),
outlineCol = paste0((mycol), 80),
cex = 2, main = "Secretome proteome (Meissner et al. 2013)")
highlightOnPlot(object = tsne_unst, pch = 21, cex = 1.7,
col = "black", bg = "gray",
foi = secretome, lwd = 2,
args = list(unst))
prettyTSNE_overlay(tsne_lps, lps, fcol = "localisation.pred", orgOrder = oo,
mainCol = paste0(lighten(mycol), 80),
outlineCol = paste0((mycol), 80),
cex = 2, main = "")
highlightOnPlot(object = tsne_lps, pch = 21, cex = 1.7,
col = "black", bg = "gray",
foi = secretome, lwd = 2,
args = list(lps))
prettyTSNE_overlay(tsne_unst, unst, fcol = "localisation.pred", orgOrder = oo,
mainCol = paste0(lighten(mycol), 80),
outlineCol = paste0((mycol), 80),
cex = 2, main = "Cell surface proteome (Kalxdorf et al 2017)")
highlightOnPlot(object = tsne_unst, pch = 21, cex = 1.7,
col = "black", bg = "gray",
foi = cell_surface, lwd = 2,
args = list(unst))
prettyTSNE_overlay(tsne_lps, lps, fcol = "localisation.pred", orgOrder = oo,
mainCol = paste0(lighten(mycol), 80),
outlineCol = paste0((mycol), 80),
cex = 2, main = "")
highlightOnPlot(object = tsne_lps, pch = 21, cex = 1.7,
col = "black", bg = "gray",
foi = cell_surface, lwd = 2,
args = list(lps))
prettyTSNE_overlay(tsne_unst, unst, fcol = "localisation.pred", orgOrder = oo,
mainCol = paste0(lighten(mycol), 80),
outlineCol = paste0((mycol), 80),
cex = 2, main = "The RNA binding proteome (Liepelt et al 2016)")
highlightOnPlot(object = tsne_unst, pch = 21, cex = 1.7,
col = "black", bg = "gray",
foi = RNAbp, lwd = 2,
args = list(unst))
prettyTSNE_overlay(tsne_lps, lps, fcol = "localisation.pred", orgOrder = oo,
mainCol = paste0(lighten(mycol), 80),
outlineCol = paste0((mycol), 80),
cex = 2, main = "")
highlightOnPlot(object = tsne_lps, pch = 21, cex = 1.7,
col = "black", bg = "gray",
foi = RNAbp, lwd = 2,
args = list(lps))
prettyTSNE_overlay(tsne_unst, unst, fcol = "localisation.pred", orgOrder = oo,
mainCol = paste0(lighten(mycol), 80),
outlineCol = paste0((mycol), 80),
cex = 2, main = "The mitochondrial and lysosomal proteome (Fu et al 2020)")
highlightOnPlot(object = tsne_unst, pch = 21, cex = 1.7,
col = "black", bg = "gray",
foi = mito_lyso, lwd = 2,
args = list(unst))
highlightOnPlot(object = tsne_unst, pch = 21, cex = 1.7,
col = "black", bg = "gray",
foi = mito, lwd = 2,
args = list(unst))
prettyTSNE_overlay(tsne_lps, lps, fcol = "localisation.pred", orgOrder = oo,
mainCol = paste0(lighten(mycol), 80),
outlineCol = paste0((mycol), 80),
cex = 2, main = "")
highlightOnPlot(object = tsne_lps, pch = 21, cex = 1.7,
col = "black", bg = "gray",
foi = mito_lyso, lwd = 2,
args = list(lps))
highlightOnPlot(object = tsne_lps, pch = 21, cex = 1.7,
col = "black", bg = "gray",
foi = mito, lwd = 2,
args = list(lps))Figure 5.13: The hyperLOPIT plots can be used as a scaffold to overlay proteins of interest, such as those identified by other subcellular proteomic studies. Shown are organellar proteins identified in four different studies, which have been overlaid onto the hyperLOPIT plots to validate their subcellular localisations. (A) Secretome proteome (Meissner et al., 2013), (B) cell surface proteome (Kalxdorf et al., 2017), (C) the RNA binding proteome (Liepelt et al., 2016) and (D) mitochondrial and lysosomal proteome (Fu et al., 2020).
6 Source code
Most of the analysis in this repo uses functions from the pRoloc and MSnbase open-source open-development Bioconductor packages. Specific code for the generation of some of the figures and analyses can be found in the R directory of this Github repo.
7 SessionInfo
R session info for this repo
## R version 4.0.5 (2021-03-31)
## Platform: x86_64-apple-darwin17.0 (64-bit)
## Running under: macOS Big Sur 10.16
##
## Matrix products: default
## BLAS: /Library/Frameworks/R.framework/Versions/4.0/Resources/lib/libRblas.dylib
## LAPACK: /Library/Frameworks/R.framework/Versions/4.0/Resources/lib/libRlapack.dylib
##
## locale:
## [1] en_GB.UTF-8/en_GB.UTF-8/en_GB.UTF-8/C/en_GB.UTF-8/en_GB.UTF-8
##
## attached base packages:
## [1] stats4 parallel stats graphics grDevices utils datasets
## [8] methods base
##
## other attached packages:
## [1] gplots_3.1.1 ggalluvial_0.12.3 circlize_0.4.12
## [4] reshape2_1.4.4 colorspace_2.0-0 kableExtra_1.3.4
## [7] knitr_1.33 RColorBrewer_1.1-2 ggrepel_0.9.1
## [10] dplyr_1.0.5 ggplot2_3.3.3 limma_3.46.0
## [13] imputeLCMD_2.0 impute_1.64.0 pcaMethods_1.82.0
## [16] norm_1.0-9.5 tmvtnorm_1.4-10 gmm_1.6-6
## [19] sandwich_3.0-0 Matrix_1.3-2 mvtnorm_1.1-1
## [22] pRolocdata_1.29.1 pRoloc_1.30.0 BiocParallel_1.24.1
## [25] MLInterfaces_1.70.0 cluster_2.1.1 annotate_1.68.0
## [28] XML_3.99-0.6 AnnotationDbi_1.52.0 IRanges_2.24.1
## [31] MSnbase_2.16.1 ProtGenerics_1.22.0 S4Vectors_0.28.1
## [34] mzR_2.24.1 Rcpp_1.0.6 Biobase_2.50.0
## [37] BiocGenerics_0.36.0
##
## loaded via a namespace (and not attached):
## [1] systemfonts_1.0.1 BiocFileCache_1.14.0 plyr_1.8.6
## [4] splines_4.0.5 digest_0.6.27 foreach_1.5.1
## [7] htmltools_0.5.1.1 viridis_0.6.0 fansi_0.4.2
## [10] magrittr_2.0.1 memoise_2.0.0 doParallel_1.0.16
## [13] mixtools_1.2.0 recipes_0.1.15 gower_0.2.2
## [16] svglite_2.0.0 askpass_1.1 rmdformats_1.0.2
## [19] lpSolve_5.6.15 prettyunits_1.1.1 rvest_1.0.0
## [22] blob_1.2.1 rappdirs_0.3.3 xfun_0.22
## [25] crayon_1.4.1 jsonlite_1.7.2 hexbin_1.28.2
## [28] survival_3.2-10 zoo_1.8-9 iterators_1.0.13
## [31] glue_1.4.2 gtable_0.3.0 ipred_0.9-11
## [34] zlibbioc_1.36.0 webshot_0.5.2 kernlab_0.9-29
## [37] shape_1.4.5 scales_1.1.1 vsn_3.58.0
## [40] DBI_1.1.1 viridisLite_0.4.0 xtable_1.8-4
## [43] progress_1.2.2 bit_4.0.4 proxy_0.4-25
## [46] mclust_5.4.7 preprocessCore_1.52.1 lava_1.6.9
## [49] prodlim_2019.11.13 sampling_2.9 httr_1.4.2
## [52] FNN_1.1.3 ellipsis_0.3.1 farver_2.1.0
## [55] pkgconfig_2.0.3 nnet_7.3-15 sass_0.3.1
## [58] dbplyr_2.1.1 utf8_1.2.1 caret_6.0-86
## [61] labeling_0.4.2 tidyselect_1.1.0 rlang_0.4.10
## [64] munsell_0.5.0 tools_4.0.5 LaplacesDemon_16.1.4
## [67] cachem_1.0.4 generics_0.1.0 RSQLite_2.2.6
## [70] evaluate_0.14 stringr_1.4.0 fastmap_1.1.0
## [73] mzID_1.28.0 yaml_2.2.1 ModelMetrics_1.2.2.2
## [76] bit64_4.0.5 caTools_1.18.2 purrr_0.3.4
## [79] randomForest_4.6-14 dendextend_1.14.0 ncdf4_1.17
## [82] nlme_3.1-152 xml2_1.3.2 biomaRt_2.46.3
## [85] rstudioapi_0.13 compiler_4.0.5 curl_4.3
## [88] e1071_1.7-6 affyio_1.60.0 tibble_3.1.0
## [91] bslib_0.2.4 stringi_1.5.3 highr_0.8
## [94] lattice_0.20-41 vctrs_0.3.7 pillar_1.6.0
## [97] lifecycle_1.0.0 BiocManager_1.30.12 GlobalOptions_0.1.2
## [100] jquerylib_0.1.3 MALDIquant_1.19.3 bitops_1.0-6
## [103] data.table_1.14.0 R6_2.5.0 affy_1.68.0
## [106] bookdown_0.21 KernSmooth_2.23-18 gridExtra_2.3
## [109] codetools_0.2-18 MASS_7.3-53.1 gtools_3.8.2
## [112] assertthat_0.2.1 openssl_1.4.3 withr_2.4.1
## [115] hms_1.0.0 grid_4.0.5 rpart_4.1-15
## [118] timeDate_3043.102 tidyr_1.1.3 coda_0.19-4
## [121] class_7.3-18 rmarkdown_2.7 segmented_1.3-3
## [124] Rtsne_0.15 pROC_1.17.0.1 lubridate_1.7.10
References
1. R Core Team. R: A language and environment for statistical computing. (R Foundation for Statistical Computing, 2017).
2. Mulvey, C. M. et al. Spatiotemporal proteomic profiling of the pro-inflammatory response to lipopolysaccharide in the thp-1 human leukaemia cell line. Nature Communicatio In review, (2021).
3. Gatto, L., Breckels, L. M., Wieczorek, S., Burger, T. & Lilley, K. S. Mass-spectrometry based spatial proteomics data analysis using pRoloc and pRolocdata. Bioinformatics (2014).
4. Gatto, L. & Lilley, K. MSnbase - an r/bioconductor package for isobaric tagged mass spectrometry data visualization, processing and quantitation. Bioinformatics 28, 288–289 (2012).
5. Perez-Riverol, Y. et al. The pride database and related tools and resources in 2019: Improving support for quantification data. Nucleic Acids Research 47, (2018).
6. Ritchie, M. E. et al. Limma powers differential expression analyses for RNA-sequencing and microarray studies. Nucleic Acids Research 43, e47–e47 (2015).
7. Kirk, P., Griffin, J. E., Savage, R. S., Ghahramani, Z. & Wild, D. L. Bayesian correlated clustering to integrate multiple datasets. Bioinformatics 28, 3290–3297 (2012).
8. Ashburner, M. et al. Gene ontology: Tool for the unification of biology. Nature genetics 25, 25–29 (2000).
9. Y. Benjamini & Hochberg, Y. Controlling the false discovery rate: A practical and powerful approach to multiple testing. Journal of the Royal Statistical Society. Series B (Methodological) 43, e47–e47 (1995).
10. Christoforou, A. et al. A draft map of the mouse pluripotent stem cell spatial proteome. Nat Commun 7, 9992 (2016).
11. Mulvey, C. M. et al. Using hyperLOPIT to perform high-resolution mapping of the spatial proteome. Nature Protocols 12, 1110–1135 (2017).
12. Breckels, L. M., Mulvey, C. M., Lilley, K. S. & Gatto, L. A bioconductor workflow for processing and analysing spatial proteomics data. F1000Research 5, (2016).
13. De Duve, C. & Beaufay, H. A short history of tissue fractionation. The Journal of cell biology 91, 293 (1981).
14. Trotter, M., Sadowski, P., Dunkley, T., Groen, A. & Lilley, K. Improved sub-cellular resolution via simultaneous analysis of organelle proteomics data across varied experimental conditions. Proteomics 10, 4213–4219 (2010).
15. Crook, O. M., Mulvey, C. M., Kirk, P. D. W., Lilley, K. S. & Gatto, L. A bayesian mixture modelling approach for spatial proteomics. PLoS Comput. Biol. 14, e1006516 (2018).
16. Crook, O. M., Breckels, L. M., Lilley, K. S., Kirk, P. D. W. & Gatto, L. A bioconductor workflow for the bayesian analysis of spatial proteomics. F1000Research 8, 446 (2019).
17. Gelman, A. & Rubin, D. B. Inference from iterative simulation using multiple sequences. Statistical Science 7, (1992).
18. Min, K.-W., Lee, S.-H. & Baek, S. J. Moonlighting proteins in cancer. Cancer Letters 370, 108–116 (2016).